简体   繁体   English

防止jQuery中的click事件多次触发

[英]Prevent click event in jQuery triggering multiple times

I have created a jQuery content switcher . 我创建了一个jQuery内容切换器 Generally, it works fine, but there is one problem with it. 一般来说,它工作正常,但它有一个问题。 If you click the links on the side multiple times, multiple pieces of content sometimes become visible. 如果多次单击侧面的链接,有时会显示多条内容。

The problem most likely lies somewhere within the click event. 问题最有可能出现在click事件中。 Here is the code: 这是代码:

$('#tab-list li a').click(
    function() {
        var targetTab = $(this).attr('href');
        if ($(targetTab).is(':hidden')) {
            $('#tab-list li').removeClass('selected');
            var targetTabLink = $(this).parents('li').eq(0);
            $(targetTabLink).addClass('selected');
            $('.tab:visible').fadeOut('slow',
                function() {
                    $(targetTab).fadeIn('slow');
                }
            );
        }
        return false;
    }
);

I have tried adding a lock to the transition so that further clicks are ignored as the transition is happening, but to no avail. 我已经尝试为转换添加锁定,以便在转换发生时忽略进一步的点击,但无济于事。 I have also tried to prevent the transition from being triggered if something is already animating, using the following: 我还尝试使用以下内容防止在某些内容已经动画时触发转换:

if ($(':animated')) {
    // Don't do anything
}
else {
   // Do transition
}

But it seems to always think things are being animated. 但它似乎总是认为事物是动画的。 Any ideas how I can prevent the animation being triggered multiple times? 有什么想法可以防止多次触发动画?

One idea would be to remove the click event at the start of your function, and then add the click event back in when your animation has finished, so clicks during the duration would have no effect. 一个想法是在函数开始时删除click事件,然后在动画结束时重新添加click事件,因此在持续时间内点击将无效。

If you have the ability to execute code when the animation has finished this should work. 如果你能够在动画结束时执行代码,那么这应该可行。

Add a variable to use as a lock rather than is(:animating). 添加一个变量用作锁而不是(:动画)。

On the click, check if the lock is set. 在单击时,检查是否已设置锁定。 If not, set the lock, start the process, then release the lock when the fadeIn finishes. 如果没有,请设置锁定,启动进程,然后在fadeIn完成时释放锁定。

var blockAnimation = false;

$('#tab-list li a').click(
    function() {
        if(blockAnimation != true){
        blockAnimation = true;
        var targetTab = $(this).attr('href');
        if ($(targetTab).is(':hidden')) {
            $('#tab-list li').removeClass('selected');
            var targetTabLink = $(this).parents('li').eq(0);
            $(targetTabLink).addClass('selected');
            $('.tab:visible').fadeOut('slow',
                function() {
                    $(targetTab).fadeIn('slow', function(){ blockAnimation=false; });
                }
            );
        }
        }
        return false;
    }
);

Well this is how i did it, and it worked fine. 那么这就是我做到的,它运作良好。

$(document).ready(function() {
    $(".clickitey").click(function () {
        if($("#mdpane:animated").length == 0) {
            $("#mdpane").slideToggle("slow"); 
            $(".jcrtarrow").toggleClass("arrow-open");
        }
    });
});

this is not doing what your code does ofcourse this is a code from my site, but i just like to point how i ignored the clicks that were happening during the animation. 这不是你的代码所做的事情,这是我网站上的代码,但我想指出我是如何忽略动画期间发生的点击。 Please let me know if this is inefficient in anyway. 无论如何,请告诉我这是否效率低下。 Thank you. 谢谢。

I toyed around with the code earlier and came up with the following modification which seems to work: 我之前玩弄了代码并提出了以下修改,似乎有效:

$('#tab-list li a').click(
    function() {
        $('.tab:animated').stop(true, true);
        var targetTab = $(this).attr('href');
        if ($(targetTab).is(':hidden')) {
            $('#tab-list li').removeClass('selected');
            var targetTabLink = $(this).parents('li').eq(0);
            $(targetTabLink).addClass('selected');
            $('.tab:visible').fadeOut('slow',
                function() {
                    $(targetTab).fadeIn('slow');
                }
            );
        }
        return false;
    }
);

All that happens is, when a new tab is clicked, it immediately brings the current animation to the end and then begins the new transition. 所有发生的情况是,当单击一个新选项卡时,它会立即将当前动画结束,然后开始新的转换。

one way would be this: 一种方式是这样的:

$('#tab-list ul li').one( 'click', loadPage );
var loadPage = function(event) {
    var $this = $(this);
    $global_just_clicked = $this;
    var urlToLoad = $this.attr('href');
    $('#content-area').load( urlToLoad, pageLoaded );
}
$global_just_clicked = null;
var pageLoaded() {
    $global_just_clicked.one( 'click', loadPage );
}

As you can see, this method is fraught with shortcomings: what happens when another tab is clicked before the current page loads? 正如您所看到的,此方法充满了缺点:在当前页面加载之前单击另一个选项卡时会发生什么? What if the request is denied? 如果请求被拒绝怎么办? what if its a full moon? 如果满月怎么办?

The answer is: this method is just a rudimentary demonstration. 答案是:这种方法只是一个基本的示范。 A proper implementation would: 适当的实施将:

  1. not contain the global variable $global_just_clicked 不包含全局变量$global_just_clicked
  2. not rely on .load() . 不依赖于.load() Would use .ajax() , and handle request cancellation, clicking of other tabs etc. 将使用.ajax() ,并处理请求取消,点击其他选项卡等。

NOTE: In most cases you need not take this round-about approach. 注意:在大多数情况下,您不需要采用这种循环方法。 I'm sure you can remedy you code in such a way that multiple clicks to the same tab would not affect the end result. 我确信您可以通过对同一选项卡的多次单击不会影响最终结果的方式来修复代码。

jrh. JRH。

One way to do this to use timeStamp property of event like this to gap some time between multiple clicks: 一种方法是使用像这样的事件的timeStamp属性来在多次点击之间缩短一些时间:

var a = $("a"),
    stopClick = 0;


a.on("click", function(e) {
  if(e.timeStamp - stopClick > 300) { // give 300ms gap between clicks
     // logic here

    stopClick = e.timeStamp; // new timestamp given
  }


});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM