忙时未发生 JavaScript 单击事件



我似乎遇到了某种并发问题,试图让点击事件发生。问题是我正在使用setInterval运行动画,但停止按钮没有触发,可能是因为 JavaScript 很忙。如果我一遍又一遍地快速点击"停止"按钮,我可以让它停止。代码如下所示:

    var timer_id = null;
    function play(){
        timer_id = setInterval( function(){ 
            time_second++;
            if( time_second == 60 ){
                time_minute++;
                time_second = 0;
            }
            render();
        }, 1000 / time_compression_factor );
        console.log( "timer id: " + timer_id );
    }
    
    function stop(){
        console.log( "stopped" );
        if( timer_id != null );
        clearInterval( timer_id );
        timer_id = null;
    }
    function drawVCRControls(){
        var width_timeslice = 7 + 3;
        var ul_x = 20 + 120 * width_timeslice + 15;
        var ul_y = viewportHeight - 40;
        var pathPlayBack    = "m 20  0  l 10 -8  l  0 16  Z";
        var pathStop        = "m 35 -8  l 16  0  l  0 16  l -16 0 Z";
        var pathPlayForward = "m 57  0  l  0 -8  l 10  8  l -10 8 Z";
        var pathStepBack    = "m 12 20  l 10 -8  l  0 16  Z  m 13 -8  l 5 0  l 0 16  l -5 0 Z";
        var pathPause       = "m 35 12  h 6 v 16  h -6 Z  m 10 0  h 6 v 16  h -6 Z ";
        var pathStepForward = "m 57 12  h 5 v 16  h -5 Z  m  8 0  l 10 8  l -10 8 Z";
        createPath( "vcrPlayBack", ul_x, ul_y, pathPlayBack, 1, "orangered", "orange", 1, 0 );
        createPath( "vcrStop", ul_x, ul_y, pathStop, 1, "orangered", "orange", 1, 0 );
        createPath( "vcrPlayForward", ul_x, ul_y, pathPlayForward, 1, "orangered", "orange", 1, 0 );    
        createPath( "vcrStepBack", ul_x, ul_y, pathStepBack, 1, "orangered", "orange", 1, 0 );
        createPath( "vcrPause", ul_x, ul_y, pathPause, 1, "orangered", "orange", 1, 0 );    
        createPath( "vcrStepForward", ul_x, ul_y, pathStepForward, 1, "orangered", "orange", 1, 0 );
        vcrPlayForward.addEventListener( "click", function(){
            play();
        }, false );
        vcrStop.addEventListener( "click", function(){
            stop();
        }, false );
    }

play()函数中的render()调用会绘制很多东西,所以我认为当它忙于绘制时,它基本上忽略了 vcrStop 按钮上的单击事件。我可以看到这一点,因为我有一个控制台.log语句,该语句记录了何时调用stop()并且当我单击 vcrStop 按钮时它不会被调用。

我知道处理程序运行正常,因为如果我在开始动画之前单击 vcrStop 按钮,它会记录到控制台中。

请注意,如果我在 1 秒处运行间隔,那么一切正常,但间隔越短,停止动画就越困难。例如,如果我使用 500 毫秒的间隔,我可能需要单击两到三次才能停止它,但是如果我使用 100 毫秒的间隔(所需的间隔),我必须非常快速地单击 10 次或更多。

如何解决这个问题?

为您的

特定问题提供一个 JSFiddle 会很有帮助,这将非常有帮助。

我认为您的问题正是您所说的 - 脚本很忙。问题是JavaScript是在单线程庄园中执行的。因此,单击事件只能在渲染完成后处理。为了使渲染的取消成为可能,您可以将渲染拆分为几个步骤,并在链式回调中调用每个步骤,即,在第一个步骤完成后,当且仅当该过程未被取消时,调用渲染的第二步。

无论如何,您提到您有一个控制台.log用于单击。渲染完成后,是否看到日志的输出?

是的,你可能是对的,render() 可能会阻止要触发的点击事件。但是,单击事件也需要一些时间才能触发,因为它是鼠标按下鼠标向上事件的组合。这可能大于您的间隔。您可以尝试使用鼠标按下事件,我认为这比单击冒泡花费的时间更少。

祝你好运

相关内容

  • 没有找到相关文章

最新更新