Как я могу временно отключить 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
Есть много способов сделать это. Например:
$(".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
Почему бы не отключить кнопку? Есть ли конкретная причина, по которой вы хотите отключить только этот список? BTB, из вашего кода я вижу, что вы выполняете вызов ajax. ТАК, вы конкретно хотите заблокировать пользователя, пока не вернется звонок? Если да, вы можете попробовать blockUI , плагин jQuery
. На какой срок вы хотите отключить прослушиватель событий щелчка? Один из способов - отвязать прослушиватель событий с помощью 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 (их всего три: успех
, ошибка
, ] complete
см. документы ), иначе active
может остаться ложным.
Я бы предложил отключить кнопку, а затем снова включить ее в процедурах завершения Ajax (успех или сбой, помните). Если вы беспокоитесь о том, что браузер не соблюдает ваше отключение кнопки, вы можете вернуть это с помощью собственного флага на кнопке (например, установить атрибут с именем data-disabled
, используя data-
как хорошая практика и совместимость с HTML5). Но если на самом деле не возникнет проблема с браузерами, которые не отключают кнопку, я, вероятно, счел бы это достаточно хорошим.
Вы можете выполнить действие в пределах щелчка на основе логического значения. При щелчке измените логическое значение и используйте 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
}
});
Я бы установил глобальную переменную для отслеживания запросов 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. (то, что я называю "добавочным" решением)
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);
Я бы использовал класс, например, «ajax-running». Событие click будет выполнено только в том случае, если элемент, по которому щелкнули, не имеет класса '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');
});
};
}
});