Предотвратить многократное нажатие в jQuery - PullRequest
9 голосов
/ 18 июня 2009

Я создал jQuery переключатель контента . В общем, работает нормально, но есть одна проблема. Если вы нажимаете ссылки на стороне несколько раз, иногда становятся видны несколько фрагментов контента.

Скорее всего, проблема заключается в событии click. Вот код:

$('#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;
    }
);

Я попытался добавить блокировку к переходу, чтобы дальнейшие щелчки игнорировались при переходе, но безрезультатно. Я также пытался предотвратить запуск перехода, если что-то уже оживляет, используя следующее:

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

Но, кажется, всегда думают, что вещи оживляются. Любые идеи, как я могу предотвратить запуск анимации несколько раз?

Ответы [ 6 ]

12 голосов
/ 18 июня 2009

Одной из идей будет удаление события click в начале вашей функции, а затем добавление события click обратно, когда анимация завершится, поэтому щелчки во время действия не будут иметь эффекта.

Если у вас есть возможность выполнить код после завершения анимации, это должно сработать.

6 голосов
/ 18 июня 2009

Добавить переменную для использования в качестве блокировки, а не (: анимация).

При нажатии проверьте, установлена ​​ли блокировка. Если нет, установите блокировку, запустите процесс, затем снимите блокировку после завершения 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;
    }
);
3 голосов
/ 05 августа 2010

Ну, вот как я это сделал, и он работал нормально.

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

это не то, что делает ваш код, конечно, это код с моего сайта, но я просто хотел бы указать, как я игнорировал клики, которые происходили во время анимации. Пожалуйста, дайте мне знать, если это неэффективно в любом случае. Спасибо.

1 голос
/ 18 июня 2009

Ранее я поиграл с кодом и придумал следующую модификацию, которая, кажется, работает:

$('#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;
    }
);

Все, что происходит, это то, что при нажатии на новую вкладку она сразу же завершает текущую анимацию и затем начинает новый переход.

0 голосов
/ 14 ноября 2014

Один из способов сделать это - использовать свойство события 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
  }


});
0 голосов
/ 18 июня 2009

в одну сторону было бы так:

$('#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 );
}

Как видите, этот метод чреват недостатками: что произойдет, если щелкнуть другую вкладку перед загрузкой текущей страницы? Что делать, если запрос отклонен? что если это полная луна?

Ответ: этот метод - просто элементарная демонстрация. Правильная реализация будет:

  1. не содержит глобальную переменную $global_just_clicked
  2. не полагайтесь на .load(). Будет использовать .ajax() и обрабатывать отмену запроса, нажатие других вкладок и т. Д.

ПРИМЕЧАНИЕ. В большинстве случаев вам не нужно использовать этот обходной подход. Я уверен, что вы можете исправить свой код таким образом, чтобы несколько кликов на одной вкладке не влияли на конечный результат.

JRH.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...