为什么我的CSS动画不适用于正确的元素?

时间:2018-03-18 03:17:52

标签: javascript html css reactjs css-animations

我试图编写一个CSS动画,当有人点击该元素时就会激活该动画(就像删除它一样)。元素被渲染为地图的一部分,因此它有点复杂。我以前没有这样做过,如果它愚蠢的话,对不起,这就是我试图做的事情。

当前正在使用以下代码进行的操作:当我点击某些内容时,正确的项目就会消失(没有任何动画),但是数组中的下一个元素会收到动画然后重新出现。但有时动画根本不会出现。为什么动画会传递错误的元素?

这是我正在渲染不同元素的地图。请注意,我为每个sport.name创建了一个id。

this.state.sports.map((sport) => {    
      let imgPath = " ";
      if(/\s/g.test(sport.name.toLowerCase())){                                        
         imgPath = 'images/' + sport.name.replace(/\s/g, '').toLowerCase() + '.png'
         } else {
         imgPath = 'images/' + sport.name.toLowerCase() + '.png'
         }                   
         return(
            <div>
              <button className="sport-button" id={sport.name} onClick={() => this.deleteSport(sport.name)}>
                 <img src={imgPath} className="sport-image" /> 
                    {sport.name}
              </button>                         
            </div>
           )   
         })

这是我拥有的deleteSport函数,它当前是onClick处理程序。在其中,我调用另一个名为exitAnimation的函数。

deleteSport = (name) => {
    for(let i of this.state.sports){
        if(i.name === name){
            let stateCopy = this.state.sports.filter(sport => sport.name !== i.name)            
            this.exitAnimation(name)
            console.log(name)
            this.setState({
                sports: stateCopy
            })            
        } 
    }
}

这是被调用的exitAnimation函数......

exitAnimation = (name) => {
    document.getElementById(name.toString()).style.animation = "deleteAnimation 2s"
}

Aaaaaand这是我的CSS样式表中出现的CSS动画...

@keyframes deleteAnimation {
  from { opacity: 1; 
  }
   to { opacity: 0; 
  }        
}

1 个答案:

答案 0 :(得分:2)

您在动画完成前删除该项目。见修改。

deleteSport = (name) => {
    for(let i of this.state.sports){
        if(i.name === name){
            const stateCopy = this.state.sports.filter(sport => sport.name !== i.name)            
            return this.exitAnimation(name, name => {
                this.setState({
                    sports: stateCopy
                })
            })         
        } 
    }
}

exitAnimation = (name, cb) => {
    document.getElementById(name.toString()).style.animation = "deleteAnimation 2s"
    // called when animation completes after 2s
    setTimeout(() => cb(name), 2000)
}

请注意,我们只是等待2秒。通常,您可以使用动画库,该动画库实际上会在动画完成时告诉您。

更新

尝试将stateCopy移动到exitAnimation回调中。 stateCopy和exitAnimation之间可能存在竞争条件

deleteSport = (name) => {
    for(let sport of this.state.sports){
        if(sport.name === name){
            return this.exitAnimation(name, name => {
                const sports = this.state.sports.filter(sport => sport.name !== name)
                this.setState({
                    sports: sports
                })
            })         
        } 
    }
}