Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 添加加载程序以响应组件_Javascript_Reactjs - Fatal编程技术网

Javascript 添加加载程序以响应组件

Javascript 添加加载程序以响应组件,javascript,reactjs,Javascript,Reactjs,我正在尝试为我的react组件实现一个加载器,当背景图像加载时,它应该显示'loading',一旦加载,它应该显示'loaded' 我在我的组件willmount()上有一个setTimeout()来测试加载程序是否按预期运行 我很难理解它是如何知道何时加载图像以及如何更改加载状态的 最好是将图像与加载程序一起放入一个单独的组件中,而不是放在Hello组件上 更新 我已经成功地使用附加到图像的onload()方法获得了一个简单的图像加载程序- Hello.js import React fr

我正在尝试为我的react组件实现一个加载器,当背景图像加载时,它应该显示'loading',一旦加载,它应该显示'loaded'

我在我的
组件willmount()
上有一个
setTimeout()
来测试加载程序是否按预期运行

我很难理解它是如何知道何时加载图像以及如何更改加载状态的

最好是将图像与加载程序一起放入一个单独的组件中,而不是放在Hello组件上

更新

我已经成功地使用附加到图像的
onload()
方法获得了一个简单的图像加载程序-

Hello.js

 import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'

const Card = styled.div`
  height: 400px;
  width:20%;
  background: url('https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg');
`
export default class Test extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentWillMount()
  {
     setTimeout(() => this.setState({loading: false}), 3000)
      console.log("componentDidMount");
  }

  render() {
    return (
      <div>
        <Card>
        <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
import React, { Component } from 'react'
import styled, { keyframes } from 'styled-components'
import { string } from 'prop-types'

const transition1 = keyframes`
  0%     { background: #F19939; }
  33.33% { background: #F8CA8F; }
  66.66% { background: #FBD8AE; }
  100%   { background: #F19939; }
`

const transition2 = keyframes`
  0%     { background: #FBD8AE; }
  33.33% { background: #F19939; }
  66.66% { background: #F8CA8F; }
  100%   { background: #FBD8AE; }
`

const transition3 = keyframes`
  0%     { background: #F8CA8F; }
  33.33% { background: #FBD8AE; }
  66.66% { background: #F19939; }
  100%   { background: #F8CA8F; }
`

const Box = styled.span`
  height: 12px;
  width: 12px;
  margin: 0 3px 0 3px;
  border-radius: 4px;
  animation: 0.4s ${transition1 } infinite;
`

const Box2 = styled(Box)`
  animation: 0.4s ${transition2 } infinite;
`

const Box3 = styled(Box)`
  animation: 0.4s ${transition3 } infinite;
`

const TextWrap = styled.div`
  display: flex;
  flex: 0 0 100%;
  justify-content: center;
  color: #fff;
`

const Para = styled.p`
  color: #fff
  padding: 19px 0 0 0;
`

const ParaLoaded = styled(Para)`
  color: #fff;
  padding: 22px 0 0 0;
`

export default class Loader extends Component {

  render() {
    return (
      <div >
        <div >

          <TextWrap>
            {
              this.props.loading
                ?
                  <Para>Loading...</Para>
                :
                  <ParaLoaded>Loaded</ParaLoaded>
            }
          </TextWrap>

        </div>
      </div>
    )
  }
}
const LoadBackgroundImage = (component, imageUrl, seconds, success, failure) => {
  let timeoutOccured = false;
  const image = new Image();
  const timeout = setTimeout(() => {
    timeoutOccured = true;
    failure();
  }, seconds * 1000);

  image.onload = () => {
    clearTimeout(timeout);
    component.style.backgroundImage = `url('${imageUrl}')`;
    if (!timeoutOccured) success();
  };
  image.src = imageUrl;
};

export default LoadBackgroundImage;
import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'
import LoadBackgroundImage from './LoadBackgroundImage'

const Card = styled.div`
  height: 400px;
  width:20%;
`
export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentDidMount() {
    LoadBackgroundImage(
      this.card,
      'https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg',
      5,
      () => this.setState({ loading: false }),
      () => console.log('The image did not load in 5 seconds')
    );
  }

  render() {
    return (
      <div>
        <Card innerRef={card => this.card = card}>
          <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
从“React”导入React
从“./Loader”导入加载程序
从“样式化组件”导入样式化
const Card=styled.div`
高度:400px;
宽度:20%;
背景:url('https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg');
`
导出默认类测试扩展React.Component{
构造函数(){
超级()
this.state={loading:true}
}
组件willmount()
{
setTimeout(()=>this.setState({loading:false}),3000)
log(“componentDidMount”);
}
render(){
返回(
)
}
}
Loader.js

 import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'

const Card = styled.div`
  height: 400px;
  width:20%;
  background: url('https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg');
`
export default class Test extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentWillMount()
  {
     setTimeout(() => this.setState({loading: false}), 3000)
      console.log("componentDidMount");
  }

  render() {
    return (
      <div>
        <Card>
        <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
import React, { Component } from 'react'
import styled, { keyframes } from 'styled-components'
import { string } from 'prop-types'

const transition1 = keyframes`
  0%     { background: #F19939; }
  33.33% { background: #F8CA8F; }
  66.66% { background: #FBD8AE; }
  100%   { background: #F19939; }
`

const transition2 = keyframes`
  0%     { background: #FBD8AE; }
  33.33% { background: #F19939; }
  66.66% { background: #F8CA8F; }
  100%   { background: #FBD8AE; }
`

const transition3 = keyframes`
  0%     { background: #F8CA8F; }
  33.33% { background: #FBD8AE; }
  66.66% { background: #F19939; }
  100%   { background: #F8CA8F; }
`

const Box = styled.span`
  height: 12px;
  width: 12px;
  margin: 0 3px 0 3px;
  border-radius: 4px;
  animation: 0.4s ${transition1 } infinite;
`

const Box2 = styled(Box)`
  animation: 0.4s ${transition2 } infinite;
`

const Box3 = styled(Box)`
  animation: 0.4s ${transition3 } infinite;
`

const TextWrap = styled.div`
  display: flex;
  flex: 0 0 100%;
  justify-content: center;
  color: #fff;
`

const Para = styled.p`
  color: #fff
  padding: 19px 0 0 0;
`

const ParaLoaded = styled(Para)`
  color: #fff;
  padding: 22px 0 0 0;
`

export default class Loader extends Component {

  render() {
    return (
      <div >
        <div >

          <TextWrap>
            {
              this.props.loading
                ?
                  <Para>Loading...</Para>
                :
                  <ParaLoaded>Loaded</ParaLoaded>
            }
          </TextWrap>

        </div>
      </div>
    )
  }
}
const LoadBackgroundImage = (component, imageUrl, seconds, success, failure) => {
  let timeoutOccured = false;
  const image = new Image();
  const timeout = setTimeout(() => {
    timeoutOccured = true;
    failure();
  }, seconds * 1000);

  image.onload = () => {
    clearTimeout(timeout);
    component.style.backgroundImage = `url('${imageUrl}')`;
    if (!timeoutOccured) success();
  };
  image.src = imageUrl;
};

export default LoadBackgroundImage;
import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'
import LoadBackgroundImage from './LoadBackgroundImage'

const Card = styled.div`
  height: 400px;
  width:20%;
`
export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentDidMount() {
    LoadBackgroundImage(
      this.card,
      'https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg',
      5,
      () => this.setState({ loading: false }),
      () => console.log('The image did not load in 5 seconds')
    );
  }

  render() {
    return (
      <div>
        <Card innerRef={card => this.card = card}>
          <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
import React,{Component}来自“React”
从“已设置样式的组件”导入已设置样式的{关键帧}
从“属性类型”导入{string}
const transition1=关键帧`
0%{背景:#F19939;}
33.33%{背景:#F8CA8F;}
66.66%{背景:#FBD8AE;}
100%{背景:#F19939;}
`
const transition2=关键帧`
0%{背景:#FBD8AE;}
33.33%{背景:#F19939;}
66.66%{背景:#F8CA8F;}
100%{背景:#FBD8AE;}
`
const transition3=关键帧`
0%{背景:#F8CA8F;}
33.33%{背景:#FBD8AE;}
66.66%{背景:#F19939;}
100%{背景:#F8CA8F;}
`
const Box=styled.span`
高度:12px;
宽度:12px;
利润率:0.3px 0.3px;
边界半径:4px;
动画:0.4s${transition1}无限;
`
const Box2=已设置样式(框)`
动画:0.4s${transition2}无限;
`
const Box3=已设置样式(框)`
动画:0.4s${transition3}无限;
`
const TextWrap=styled.div`
显示器:flex;
弹性:0.100%;
证明内容:中心;
颜色:#fff;
`
const Para=styled.p`
颜色:#fff
填充:19px0;
`
const ParaLoaded=styled(Para)`
颜色:#fff;
填充:22px0;
`
导出默认类加载器扩展组件{
render(){
返回(
{
这是道具
?
加载。。。
:
加载
}
)
}
}
您可以这样做:

LoadBackgroundImage.js

 import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'

const Card = styled.div`
  height: 400px;
  width:20%;
  background: url('https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg');
`
export default class Test extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentWillMount()
  {
     setTimeout(() => this.setState({loading: false}), 3000)
      console.log("componentDidMount");
  }

  render() {
    return (
      <div>
        <Card>
        <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
import React, { Component } from 'react'
import styled, { keyframes } from 'styled-components'
import { string } from 'prop-types'

const transition1 = keyframes`
  0%     { background: #F19939; }
  33.33% { background: #F8CA8F; }
  66.66% { background: #FBD8AE; }
  100%   { background: #F19939; }
`

const transition2 = keyframes`
  0%     { background: #FBD8AE; }
  33.33% { background: #F19939; }
  66.66% { background: #F8CA8F; }
  100%   { background: #FBD8AE; }
`

const transition3 = keyframes`
  0%     { background: #F8CA8F; }
  33.33% { background: #FBD8AE; }
  66.66% { background: #F19939; }
  100%   { background: #F8CA8F; }
`

const Box = styled.span`
  height: 12px;
  width: 12px;
  margin: 0 3px 0 3px;
  border-radius: 4px;
  animation: 0.4s ${transition1 } infinite;
`

const Box2 = styled(Box)`
  animation: 0.4s ${transition2 } infinite;
`

const Box3 = styled(Box)`
  animation: 0.4s ${transition3 } infinite;
`

const TextWrap = styled.div`
  display: flex;
  flex: 0 0 100%;
  justify-content: center;
  color: #fff;
`

const Para = styled.p`
  color: #fff
  padding: 19px 0 0 0;
`

const ParaLoaded = styled(Para)`
  color: #fff;
  padding: 22px 0 0 0;
`

export default class Loader extends Component {

  render() {
    return (
      <div >
        <div >

          <TextWrap>
            {
              this.props.loading
                ?
                  <Para>Loading...</Para>
                :
                  <ParaLoaded>Loaded</ParaLoaded>
            }
          </TextWrap>

        </div>
      </div>
    )
  }
}
const LoadBackgroundImage = (component, imageUrl, seconds, success, failure) => {
  let timeoutOccured = false;
  const image = new Image();
  const timeout = setTimeout(() => {
    timeoutOccured = true;
    failure();
  }, seconds * 1000);

  image.onload = () => {
    clearTimeout(timeout);
    component.style.backgroundImage = `url('${imageUrl}')`;
    if (!timeoutOccured) success();
  };
  image.src = imageUrl;
};

export default LoadBackgroundImage;
import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'
import LoadBackgroundImage from './LoadBackgroundImage'

const Card = styled.div`
  height: 400px;
  width:20%;
`
export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentDidMount() {
    LoadBackgroundImage(
      this.card,
      'https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg',
      5,
      () => this.setState({ loading: false }),
      () => console.log('The image did not load in 5 seconds')
    );
  }

  render() {
    return (
      <div>
        <Card innerRef={card => this.card = card}>
          <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
Hello.js

 import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'

const Card = styled.div`
  height: 400px;
  width:20%;
  background: url('https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg');
`
export default class Test extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentWillMount()
  {
     setTimeout(() => this.setState({loading: false}), 3000)
      console.log("componentDidMount");
  }

  render() {
    return (
      <div>
        <Card>
        <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
import React, { Component } from 'react'
import styled, { keyframes } from 'styled-components'
import { string } from 'prop-types'

const transition1 = keyframes`
  0%     { background: #F19939; }
  33.33% { background: #F8CA8F; }
  66.66% { background: #FBD8AE; }
  100%   { background: #F19939; }
`

const transition2 = keyframes`
  0%     { background: #FBD8AE; }
  33.33% { background: #F19939; }
  66.66% { background: #F8CA8F; }
  100%   { background: #FBD8AE; }
`

const transition3 = keyframes`
  0%     { background: #F8CA8F; }
  33.33% { background: #FBD8AE; }
  66.66% { background: #F19939; }
  100%   { background: #F8CA8F; }
`

const Box = styled.span`
  height: 12px;
  width: 12px;
  margin: 0 3px 0 3px;
  border-radius: 4px;
  animation: 0.4s ${transition1 } infinite;
`

const Box2 = styled(Box)`
  animation: 0.4s ${transition2 } infinite;
`

const Box3 = styled(Box)`
  animation: 0.4s ${transition3 } infinite;
`

const TextWrap = styled.div`
  display: flex;
  flex: 0 0 100%;
  justify-content: center;
  color: #fff;
`

const Para = styled.p`
  color: #fff
  padding: 19px 0 0 0;
`

const ParaLoaded = styled(Para)`
  color: #fff;
  padding: 22px 0 0 0;
`

export default class Loader extends Component {

  render() {
    return (
      <div >
        <div >

          <TextWrap>
            {
              this.props.loading
                ?
                  <Para>Loading...</Para>
                :
                  <ParaLoaded>Loaded</ParaLoaded>
            }
          </TextWrap>

        </div>
      </div>
    )
  }
}
const LoadBackgroundImage = (component, imageUrl, seconds, success, failure) => {
  let timeoutOccured = false;
  const image = new Image();
  const timeout = setTimeout(() => {
    timeoutOccured = true;
    failure();
  }, seconds * 1000);

  image.onload = () => {
    clearTimeout(timeout);
    component.style.backgroundImage = `url('${imageUrl}')`;
    if (!timeoutOccured) success();
  };
  image.src = imageUrl;
};

export default LoadBackgroundImage;
import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'
import LoadBackgroundImage from './LoadBackgroundImage'

const Card = styled.div`
  height: 400px;
  width:20%;
`
export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentDidMount() {
    LoadBackgroundImage(
      this.card,
      'https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg',
      5,
      () => this.setState({ loading: false }),
      () => console.log('The image did not load in 5 seconds')
    );
  }

  render() {
    return (
      <div>
        <Card innerRef={card => this.card = card}>
          <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}
从“React”导入React
从“./Loader”导入加载程序
从“样式化组件”导入样式化
从“./LoadBackgroundImage”导入LoadBackgroundImage
const Card=styled.div`
高度:400px;
宽度:20%;
`
导出默认类Hello.Component{
构造函数(){
超级()
this.state={loading:true}
}
componentDidMount(){
加载背景图像(
这张卡,
'https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg',
5.
()=>this.setState({loading:false}),
()=>console.log('映像在5秒内未加载')
);
}
render(){
返回(
this.card=card}>
)
}
}

在render()中,您使用innerRef获取对卡组件的引用,并将其保存在this.card中。然后在componentDidMount中,您使用此引用和LoadBackgroundImage函数来加载图像,并在加载时进行监视。如果在给定次数内加载映像,将调用第二次成功回调,否则将调用失败回调。映像在5秒后仍可加载,但不会调用成功回调。如果你想被调用,你可以跳过这个复选框:
如果(!timeoutoccurrent)
在LoadBackgroundImage函数中。

这看起来不错,你能用它来检查一个组件是否正在加载吗?@tomharrison,我不确定当你直接用
背景:url(…)设置它时,是否有办法检查背景图像是否正在加载
。可能不会。