如何防止onclick监听器的垃圾邮件?

时间:2016-02-10 16:45:59

标签: javascript jquery

这对我来说是一个新问题,我一直无法找到相关信息。

我有一个简单的onclick监听器,可以顺利滚动到页面上的目标。以下是代码:

$(".nav-scroll").click(function (event) {
    var ID = this.hash;
    //has a few extra conditionals here specific to the page
    $('html,body').animate({ scrollTop: $(ID).offset().top }, 1000);
});

最终,情况是此函数需要时间来执行。没有多少时间,但如果有人在页面上发送链接并且浏览器开始排队函数调用,它确实会加起来。现在垃圾邮件是一种极端的情况,但即使连续3或4次点击,它也会阻碍用户体验,而他们无法向下滚动页面,因为页面正试图将它们滚动回目标3到4次。

我所有的研究结果都是检查一个窗口是否有一个事件监听器已经在这里找到:JavaScript - how to check if event already added或者在一个元素上列出所有事件监听器:jQuery find events handlers registered with an object但是没有什么可以检查是否有东西正在运行。

是否可以通过在执行前执行或通过其他方法在页面上转储所有先前的侦听器调用来防止此副作用?或者这是JavaScript不提供的东西?如果是这样,是否存在解决此问题的策略,例如检查函数是否已在执行?

3 个答案:

答案 0 :(得分:2)

从评论中的对话中,听起来您希望用户能够以他们想要的速度点击元素,并让它中断现有动画并开始新动画,而不是将它们排队并使其在页面上滚动。您只需使用stop

即可实现此目的
$(".nav-scroll").click(function (event) {
    var ID = this.hash;
    //has a few extra conditionals here specific to the page

    //call stop to kill old animations
    $('html,body').stop().animate({ scrollTop: $(ID).offset().top }, 1000);
});

去抖动方法会阻止它们在动画结束前完全点击,而不是让它们点击一个元素,意识到它们点击了错误的位置并快速点击了正确的元素。

答案 1 :(得分:1)

你需要这个:

var debounce = false;
$(".nav-scroll").click(function (event) {
    if (debounce) return;
    debounce = true;
    var ID = this.hash;
    //has a few extra conditionals here specific to the page
    $('html,body').animate({ scrollTop: $(ID).offset().top}, 1000, function() {debounce=false;});
});

基本上,它会一直触发onclick事件,直到它向上滚动,然后启用事件。

答案 2 :(得分:1)

你可以在油门中包裹onClick功能,以防止它在滚动时再次执行。

像这样:

// lodash is defined here as _

var animationTime = 1000;

var scrollTo = _.throttle(function (event) {
    var ID = this.hash;
    //has a few extra conditionals here specific to the page
    $('html,body').animate({ scrollTop: $(ID).offset().top }, animationTime);
}, animationTime);

$(".nav-scroll").click(scrollTo);

这种情况是用户第一次点击该函数被调用但是如果他们在时间范围内(1000ms)再次单击,则该函数不会再次执行。只有在时间过后,用户才能再次调用该功能。

在这里您可以找到lodash throttle的文档: https://lodash.com/docs#throttle