jQuery - Как я могу временно отключить прослушиватель событий onclick после того, как событие было запущено? - PullRequest
37 голосов
/ 17 декабря 2009

Как временно отключить прослушиватель событий onclick (предпочтительно jQuery) после запуска события?

Пример:

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

$(".btnRemove").click(function(){
   $(this).attr("src", "/url/to/ajax-loader.gif");
   $.ajax({
        type: "GET",
        url: "/url/to/django/view/to/remove/item/" + this.id,
        dataType: "json",
        success: function(returned_data){
            $.each(returned_data, function(i, item){
              // do stuff                       
     });
   }
});

Большое спасибо,

Aldo

Ответы [ 10 ]

66 голосов
/ 17 декабря 2009

Есть много способов сделать это. Например:

$(".btnRemove").click(function() {
    var $this = $(this);
    if ($this.data("executing")) return;
    $this
        .data("executing", true)
        .attr("src", "/url/to/ajax-loader.gif");
    $.get("/url/to/django/view/to/remove/item/" + this.id, function(returnedData) {
        // ... do your stuff ...
        $this.removeData("executing");
    });
});

или

$(".btnRemove").click(handler);

function handler() {
    var $this = $(this)
        .off("click", handler)
        .attr("src", "/url/to/ajax-loader.gif");
    $.get("/url/to/django/view/to/remove/item/" + this.id, function(returnedData) {
        // ... do your stuff ...
        $this.click(handler);
    });
}

Мы также можем использовать делегирование событий для более ясного кода и повышения производительности:

$(document).on("click", ".btnRemove:not(.unclickable)", function() {
    var $this = $(this)
        .addClass("unclickable")
        .attr("src", "/url/to/ajax-loader.gif");
    $.get("/url/to/django/view/to/remove/item/" + this.id, function(returnedData) {
        // ... do your stuff ...
        $this.removeClass("unclickable");
    });
});

Если нам не нужно повторно включать обработчик после его выполнения, тогда мы можем использовать метод .one(). Он связывает обработчики, которые должны быть выполнены только один раз. См. Документы JQuery: http://api.jquery.com/one

19 голосов
/ 17 декабря 2009

Как долго вы хотите отключить прослушиватель события click? Один из способов - отсоединить прослушиватель событий, используя jQuery unbind http://docs.jquery.com/Events/unbind.

Но лучше всего не привязывать событие, а связывать его позже. Вместо этого используйте логическое значение.

var active = true;
$(".btnRemove").click(function() {
    if (!active) {
        return;
    }
    active = false;
    $(this).attr("src", "/url/to/ajax-loader.gif");
    $.ajax({
        type: "GET",
        url: "/url/to/django/view/to/remove/item/" + this.id,
        dataType: "json",
        success: function(returned_data) {
            active = true; // activate it again !
            $.each(returned_data, function(i, item) {
                // do stuff                       
            });
        }
    });
});

edit: , чтобы быть в безопасности, вам следует также позаботиться о других подпрограммах завершения ajax (их всего три: success, error, complete см. Документы ) или active может остаться ложным.

5 голосов
/ 17 декабря 2009

почему бы не отключить кнопку? По какой-то конкретной причине вы хотите отключить этот список только? BTB, из вашего кода я вижу, что вы делаете вызов ajax. ТАК вы специально хотите заблокировать пользователя, пока звонок не вернется? Если да, вы можете попробовать blockUI , плагин jQuery

3 голосов
/ 17 декабря 2009

Я бы настроил глобальную переменную для отслеживания запросов AJAX ...

var myApp = {
  ajax: null
}

А затем немного магии, чтобы остановить одновременные запросы ...

// Fired when an AJAX request begins
$.ajaxStart(function() { myApp.ajax = 1 });

// Fired when an AJAX request completes
$.ajaxComplete(function() { myApp.ajax = null });

// Fired before an AJAX request begins
$.ajaxSend(function(e, xhr, opt) {
  if(myApp.ajax != null) {
    alert("A request is currently processing. Please wait.");
    xhr.abort();
  }
});

При таком подходе вам не нужно возвращаться к своему коду и изменять каждый из ваших вызовов AJAX. (то, что я называю «добавлением» решения)

2 голосов
/ 17 декабря 2009

Я бы использовал класс, например, «ajax-running». Событие click будет выполнено только в том случае, если у элемента clicked отсутствует класс 'ajax-running'. Как только вы завершите вызов ajax, вы можете удалить класс 'ajax-running', чтобы его можно было снова щелкнуть.

$(".btnRemove").click(function(){
    var $button         = $(this);
    var is_ajaxRunning  = $button.hasClass('ajax-running');
    if( !is_ajaxRunning ){
        $.ajax({
            ...
            success: function(returned_data) {
                ...
                $button.removeClass('ajax-running');
            });
        };
    }   
});
2 голосов
/ 17 декабря 2009

Вы можете выполнить действие в пределах клика, основываясь на логическом значении. При нажатии измените логическое значение и используйте setTimeout (), чтобы вернуть его через несколько секунд. Это фактически ограничит пользователя нажатием кнопки только один раз каждые несколько секунд.

var isEnabled = true;

$("a.clickMe").click(function(e){
  e.preventDefault();
  if (isEnabled == true) {
    isEnabled = false; // disable future clicks for now
    do_Something();
    setTimeout(function(){
      isEnabled = true;
    }, 3000); // restore functionality after 3 seconds
  }
});
1 голос
/ 29 сентября 2011

Если вы публикуете через ajax, вы можете отключить кнопку при нажатии и включить ее после завершения процесса. Но если вы отправляете сообщение обратно, вы не можете просто отключить кнопку. Отключение кнопки приводит к тому, что событие щелчка на стороне сервера не срабатывает. Так что просто спрячьте кнопку при нажатии и покажите удобное для пользователя сообщение. Помогает пост как отключить кнопку asp.net при обратной передаче .

1 голос
/ 17 декабря 2009
var ajaxAction = function() {
    var ele = $(this);
    ele.unbind("click", ajaxAction);
    ele.attr("src", "/url/to/ajax-loader.gif");
    $.ajax({
        type: "GET",
        url: "/url/to/django/view/to/remove/item/" + this.id,
        dataType: "json",
        success: function(returned_data) {
            $.each(returned_data, function(i, item) {
            });
        },
        complete: function() {
            ele.bind("click", ajaxAction);
        }
    });
}
$(".btnRemove").click(ajaxAction);
1 голос
/ 17 декабря 2009

Я бы предложил отключить кнопку, а затем снова включить ее в ваших подпрограммах завершения Ajax (помните, успех или сбой). Если вы беспокоитесь о том, что браузер не уважает отключение кнопки, вы можете сделать это с собственным флагом на кнопке (например, установить атрибут с именем data-disabled, используя префикс data- в качестве хорошей практики и использовать HTML5). совместимый). Но если учесть, что браузеры не могут отключить кнопку, то, скорее всего, возникнут проблемы, я бы посчитал это достаточно хорошим.

0 голосов
/ 30 декабря 2015

Вы также можете просто спрятать кнопку (или содержащий div)

$(".btnRemove").click(function() {
   $(this).hide();
   // your code here...
})

и вы можете просто позвонить .show (), если вам нужно отобразить его снова.

Также, в зависимости от вашего варианта использования, вы должны рассмотреть возможность использования оверлея загрузки вместо

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