JS中draw()函数的事件冒泡

Event-bubbling of a draw() function in JS

以下代码片段展示了核心结构:

编辑 1:

var smthing = 0;
change_name_button.addEventListener('click', function(event){
    // some query
    // .....

    // result from query
    data = res.name.coords;

    // tried to make the function go to GC
    smthing = null;
    delete smthing;
    smthing = new drawMouseMovement(data);

    event.stopPropagation();
}, false);      

function drawMouseMovement(data){
    // bunch of variables set for drawing function
    // .....
    // .....
    var test = 0;

    // draw something to canvas until end "maxLength" is reached
    var draw = function() {
        if(t < maxLength){
            // redraw some stuff to canvas
            // .....
        }else{
            return;
        }
    }

    // function to play pause and replay the drawing on canvas
    function playPause(boolPP, boolRP){
        if(boolPP){
            test = setInterval(draw, 10);
        }else{
            clearInterval(test);
        }
        if(boolRP){
            // some params being reset
            // .....

            test = setInterval(draw, 10);
        }
    }

    function play(event){
        playPause(true, false);
        event.stopPropagation();
    }

    function pause(event){
        playPause(false, false);
        event.stopPropagation();
    }

    function replay(event){
        playPause(false, true);
        event.stopPropagation();
    }

    play_button.addEventListener('click', play, false);

    pause_button.addEventListener('click', pause, false);

    replay_button.addEventListener('click', replay, false);
}

每次单击 change_name_button 时,都会使用新参数调用 drawMouseMovement()

以下问题:当绘制函数在再次点击change_name_button之前没有达到return时,同一个函数有两个实例同时绘制两个不同的东西。只有最后调用的函数实例才能绘制。

我尝试删除指向函数 clearInterval()removeEventListener 的指针。但我似乎没有让这些工作。

我希望我的问题很清楚。 提前致谢。

编辑

问题的简单复制。 some_button点击一次,每250ms打印一次smt。 some_button 是否被第二次点击,smt 每 125 毫秒打印一次等等。如何在下一次点击时覆盖 printer() 的第一个实例?

some_button.addEventListener('click', foo, false);

function foo(event) {
    printer();
    event.stopPropagation();
}

function printer(){
    setInterval(function() {
        console.log("smt");
    }, 250);
}

更新 2

A simple replication of the problem. Is some_button clicked once, smt is printed every 250ms. Is some_button clicked a second time, smt is printed every 125ms etc. How do I overwrite the first instance of printer() with the next click?

不行!不要杀死该功能,让它继续运行。首先,您需要一个计数器来计算点击次数,以便该函数知道它已被第二次点击。其次,只需为第二次单击按钮添加额外的行为,在这种情况下,您将减半时间间隔。

好吧,当我说 JavaScript 时间很古怪时,我的意思是 fu#@3d。 setInterval 需要 clearInterval 来阻止它。大多数文章和教程都没有说的是该死的 setInterval 仍然存在,因此将其设为 null 将允许您创建一个新的。我决定制作一个构造函数计时器。

  • 演示有一个按钮,点击它会每2秒打印'smt'加上点击次数开始一个新的间隔。

  • 'Go' 按钮被 'Stop' 按钮取代,一旦点击它就会像宣传的那样——停止

  • 再次点击是'Go'按钮,不过这次是每秒打印一次

  • 起泡、冲洗、重复。

用一些原型魔法重构这个演示,你得到了一个 class。

PLUNKER - TIMER CONSTRUCTOR

PLUNKER - 1 EVENTLISTENER, MULTIPLE EVENT.TARGETS

片段

<!DOCTYPE html>
<html>
<head>
<style>
.on { display: block; }
button { display: none; }
</style>
</head>
<body>

<button id="btn1" class="on">Go</button><button id="btn2" class="">Stop</button>
<script>
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
var counter = 0;
var timer = new Timer();
btn1.addEventListener('click', xStart, false);
btn2.addEventListener('click', xStop, false);

function xStart(event) { 
  timer.term;
  counter++;
  timer.start(counter);
 btn1.classList.toggle('on');
 btn2.classList.toggle('on');

 event.stopPropagation(); 
}

function xStop(event) {
 timer.term();
 btn1.classList.toggle('on');
 btn2.classList.toggle('on');
 event.stopPropagation(); 
}

function Timer(c){
  var self = this;

  self.start = function(c){
  var t = self.printer(c);
    self.interval = setInterval(function() { self.printer(c); },t);
  };
  
 self.term = function(){
  self.clear = clearInterval(self.interval);
  self.null;
 };
 
  self.printer = function(x){
    var d = (x % 2 === 0) ? 2 : 1;
   var t = 2000 / d;
   console.log('smt'+x+' t: '+t);
   return t;
  };
}

</script>

</body>
</html>

更新 1

以下 Plunker 演示了如何使唯一的 eventListener 成为所有按钮共享为父元素的元素。

PLUNKER


你的 eventListeners()

None 有捕获阶段的东西,虽然我相信默认情况下它是 false,但还是尝试将它设置为 false。

change_name_button.addEventListener('click', function(event){


    // some query
    // .....

    // result from query
    data = res.name.coords;

    // tried to make the function go to GC
    smthing = null;
    delete smthing;
    smthing = new drawMouseMovement(data);

    event.stopPropagation();
}, false);  

^^^^^^^^======有捕获阶段`

在其他事件处理程序上也使用 event.stopPropagation();,并将其放置在处理程序的末尾附近。不要忘记传递 (event) 对象。

   function play(event){
        playPause(true, false);
        event.stopPropagation();
    }

    function pause(event){
        playPause(false, false);
        event.stopPropagation();
    }

    function replay(event){
        playPause(false, true);
        event.stopPropagation();
    }

 play_button.addEventListener('click', play, false);

 pause_button.addEventListener('click', pause, false);

 replay_button.addEventListener('click', replay, false);

此外,如果这不能解决问题,那么您需要 post 和 HTML,因为您的 event.targetevent.currentTarget 的布局可能必须是已调整。

编辑

尝试更改 if else

function drawMouseMovement(data){
    // bunch of variables set for drawing function
    // .....
    // .....
    var test = 0;

    // draw something to canvas until end "maxLength" is reached
    var draw = function() {
        if(t < maxLength){
            // redraw some stuff to canvas
            // .....
        }
        // when t has reached maxlength, then it should quit?
        return false;
    }