【问题标题】:Force gif reload in React在 React 中强制重新加载 gif
【发布时间】:2020-01-11 11:09:43
【问题描述】:

我有一个包含 3 个步骤的模态组件。在第一步中,我有一个没有循环的 gif(换句话说,gif 不是无限的 gif)。当我打开模态并返回第一步时,我希望 gif 重新启动动画并循环一次。

我的问题是:当我第一次显示 gif 时,浏览器下载 gif 并且 gif 工作正常,但之后浏览器从缓存中获取 gif 并且不会重新启动。因此,当我关闭模态框并再次打开或再次返回第一步时,就好像我有一张图像而不是 gif。

限制:我不能多次下载gif,所以不能放?a=${Math.random()强制gif再次循环播放。

我尝试了什么:

1) 当我不在第一步并且未打开模式时,我试图将 src 放在 img 标记中。当我在第一步并打开模式时,我将 gif 放在 img 标签的 src 中

2)我尝试做与第一次尝试相同的事情,但使用另一个 gif

3) 我尝试在模态组件中执行与尝试 1 和 2 相同的操作,并将 src 传递给 step children 组件

4) 当我不在第一步且模态未打开时,我试图从 DOM 中删除 img 标记

我的简化组件:

export class Modal extends React.PureComponent {
  state = { step: FIRST_STEP }

  render() {
    {currentStep === FIRST_STEP && this.renderFirstStep()}
    {currentStep === SECOND_STEP && this.renderSecondStep()}
  }

  renderFirstStep() {
    return <FirstStep />
  }
}

export class FirstStep extends React.Component {
  render() {
    return (
      <img src={gif} alt='gif' />
    )
  }
}

提前致谢

【问题讨论】:

    标签: javascript html css reactjs


    【解决方案1】:

    您可以通过清除图像 src 然后重新设置来重新启动非无限 gif。

    在 reactJS 中执行此操作的方法是使用组件状态和零长度超时来推送到下一个刻度

    class ReloadableGif extends React.Component {
      constructor(props){
        super(props)
        this.state = {
          gif: 'http://insightgraphicdesign.net/wp-content/uploads/2014/07/coke-responsive-logo.gif',
          loaded: 'http://insightgraphicdesign.net/wp-content/uploads/2014/07/coke-responsive-logo.gif'
        }
      }
      
      reloadGif = () => {
        this.setState({loaded: ''})
        setTimeout(() => {
          this.setState({loaded: this.state.gif})
        }, 0)
      }
      
      render(){
        return <div>
          <img src={this.state.loaded} />
          <button onClick={this.reloadGif}>Replay Animation</button>
        </div>
      }
    }
    
    ReactDOM.render(
      <ReloadableGif />,
      document.getElementById("react")
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <main id="react">
    http://insightgraphicdesign.net/wp-content/uploads/2014/07/coke-responsive-logo.gif
    </main>

    【讨论】:

    • 它确实工作得很好,但是,我可以在两个加载的图像之间看到一种“跳跃”。就像 0.5s 有一个空白图像。有点烦,有人解决这个问题吗?
    • @LukyVj 要么获取实际的重复 gif,要么获取第一帧的静态图像,并将其用作循环之间的源
    【解决方案2】:
    import welcomeGif from 'modules/Onboarding/assets/welcomeGif.gif'
    
    export class FirstStep extends React.Component {
    
      constructor() {
        super()
    
        this.src = welcomeGif
      }
    
      render() {
        if (this.gif)
          this.gif.src = this.src
    
        return(
          <img
            src={this.src}
            alt='welcomeGif'
            ref={input => this.gif = input}
          />
        )
      }
    }
    

    【讨论】:

      【解决方案3】:

      这是我在 div 中显示的 gif 的实现。如果 div 被隐藏,则 gif 设置为空字符串。这样可以确保每次显示 div 时 gif 都会被动画化。

      import path1 from '../myGif.gif'
      renderGif(show) {
          //set myGif and styleToDisplay for the case where
          //the div will be shown
          let myGif = path1
          var styleToDisplay = {
              position:"absolute",
          }
      
          //if div will not be shown, set div to hidden and 
          //myGif=""
          if (!show) {
              myGif = ""
              styleToDisplay = {display: "none"}
          }
      
          //instead of just returning null here when div 
          //is not shown, return a hidden div where myGif = ""
          return(
              <div
                  onClick={this.toggleShow}
                  style={styleToDisplay}>
      
                  <img src={myGif} width="250px" height="250px"/>
              </div>
          );
      }
      
      
      toggleShow = () => {
          let t = this.state.show
          this.setState({
              show: !t,
          })
      }
      
      //call this function from another component 
      //or wherever you want to show the gif
      showGif () => {
          this.setState({
              show: true,
          })
      }
      
      //main render function
      render() {
          return (
              {this.renderGif(this.state.show}
          )
      }
      

      【讨论】:

        【解决方案4】:

        我不确定这是否会有所帮助,但您可以使用此包添加环回 https://www.npmjs.com/package/react-typing-animation

        【讨论】:

        • 感谢您的回复,但这个包不适合我的用例:/
        猜你喜欢
        • 2016-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-16
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多