在Javascript中双重激活引用self的函数

时间:2017-10-25 14:19:50

标签: javascript jquery

我使用的是一个简单的脚本:

    如果用户之前没有点击(<使用setTimeout),
  • 会在3秒后显示一条消息,

  • 然后如果用户在5秒内点击,那么该消息不应出现在定义的setTimeout中,

  • 如果用户未点击5秒钟,则在此前一次点击后,用户将看到该消息等等...

  • 这就像一个循环。

我的脚本实际上有效,但我有一个问题,因为它似乎是“以指数方式”双击。我认为我的错误是我如何创建这个“循环”并自我引用内部的setTimerForMsg。

这是一个演示:https://jsfiddle.net/3wm7z576/11/

以下是代码:

HTML

<div id="zone">
  <span id="msg" class="displayNone">this is the messager</span>
</div>

JS

setTimerForMsg(3000, 5000);

function setTimerForMsg(initial_timelaps, new_timelaps) {
      var timer = setTimeout(showMsg, initial_timelaps);
      $("#zone").on('click', function(e) {
        //if user clicks before msg appears (but after timer was initiated )
        clearTimeout(timer);
        //if user went beyond timer laps and msg already visible on Step (n)
        //remove it when move to Step (n+1)
        $('#msg').addClass('displayNone');
        console.log("message1");
        //loop the process for the next Step
        setTimerForMsg(new_timelaps, new_timelaps);
      });
    }
    function showMsg() {
      $('#msg').removeClass('displayNone');
      console.log('message2');
    }

这个问题很重要,因为虽然这个脚本很简单,但是在我的真实应用程序中,它会做其他可能会耗尽浏览器性能的事情,所以我不能让它们完成64次!

你可以在Demo的控制台中看到这里,每次点击事件发生两次:2次,然后是4次然后是8次,然后是16次,然后是32次,依此类推......

enter image description here

2 个答案:

答案 0 :(得分:4)

使用$("#zone").off('click', ...删除之前添加的eventListner。否则,您只是添加了越来越多的点击操作。

Documentation here

答案 1 :(得分:1)

首先,你的new_timelaps参数未被使用,这可能会引起一些混淆。

至于日志的指数增长,这是因为你没有删除你的事件监听器这一事实,所以每次你的间隔时间都过去了或你点击你的按钮另一个具有相同功能的点击事件适用于你的按钮。

如何解决这个问题是通过使用 $( "#zone").unbind( "click" ) 确保该事件仅适用一次,不再获得批准或旧的被删除。