D3,javascript 具有 setInterval 和 clearInterval 以及事件处理程序的函数范围

D3, javascript function scope with setInterval and clearInterval and event handler

我正在使用一个按钮来启动、停止和恢复 D3 中的动画。

在 'animateTheMap' 函数中,我将 setInterval 分配给 'animateTimer' 以开始动画,并将点击事件附加到同一按钮以使用回调函数 'stopAnimateTheMap' 停止动画。

但是stopAnimateTheMap函数看不到'animateTimer';因此抛出“未定义 animateTimer”。

1) 我需要合并两个函数还是有办法解决这个问题? 2) 我向同一个按钮添加多个 'click' 事件来播放和停止动画。这是处理事件的最佳/适当方式吗?我最初为每个事件创建了每个变量并将它们分配给按钮。

谢谢,

var animateMapButton = d3.select('body').append('button').attr({   
                                        class: "button",
                                        id: "animateMap"})
                              .text("Animate the map")

animateMapButton.on("click", animateTheMap)

function animateTheMap(){
                                    animateMapButton.text("Stop the Animation")
                                    animateMapButton.on('click',stopAnimateTheMap)
                                    i=0;                      

                                    var animateTimer = setInterval(function(){

                                        if(i<yearArray.length){
                                             i++;
                                             d3.select('text.selected').classed('selected',false)
                                             d3.select('#year'+yearArray[i]).classed('selected',true)
                                             updateMapColor(yearArray[i])

                                          }
                                        else{
                                          clearInterval(animateTimer)
                                        }
                                      },2500)
                          }


 function stopAnimateTheMap(){

                                  clearInterval(animateTimer)    
                                  animateMapButton.text("Animate the map")                                        
                                  animateMapButton.on("click",animateTheMap)
                              }

对于1):你只需要在函数外声明animateTimer变量即可。

对于 2):我只使用一个点击处理程序在动画和不动画之间切换。

var animateMapButton = d3.select('body').append('button').attr({   
        class: "button",
        id: "animateMap"})
    .text("Animate the map")

animateMapButton.on("click", toggleAnimating)

var animateTimer;
var isAnimating = false

function toggleAnimating(){
    if (isAnimating) {
        clearInterval(animateTimer)    
        animateMapButton.text("Animate the map")                                        
    }
    else {
        animateMapButton.text("Stop the Animation")
        i=0;                      

        animateTimer = setInterval(function(){

            if(i<yearArray.length){
                i++;
                d3.select('text.selected').classed('selected',false)
                d3.select('#year'+yearArray[i]).classed('selected',true)
                updateMapColor(yearArray[i])

            }
            else{
                clearInterval(animateTimer)
            }
        },2500)
    }

    isAnimating = !isAnimating;
}