How can I temporarily disable the onclick event listener, (jQuery preferred), after the event has been fired?
如何在事件被触发后暂时禁用onclick事件侦听器(jQuery首选)?
Example:
例子:
After the user clicks on the button and fires this function below, I want to disabled the onclick listener, therefore not firing the same command to my django view.
在用户单击按钮并触发下面的函数之后,我希望禁用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
});
}
});
Thanks a lot,
非常感谢,
Aldo
奥尔多
10 个解决方案
#1
65
There are a lot of ways to do it. For example:
有很多方法可以做到这一点。例如:
$(".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");
});
});
or
或
$(".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);
});
}
We can also use event delegation for clearer code and better performance:
我们也可以使用事件委托来更清晰的代码和更好的性能:
$(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");
});
});
If we don't need to re-enable the handler after it has been executed, then we can use the .one()
method. It binds handlers that are to be executed only once. See jQuery docs: http://api.jquery.com/one
如果我们不需要在处理程序执行之后重新启用它,那么我们可以使用.one()方法。它绑定只执行一次的处理程序。看到jQuery文档:http://api.jquery.com/one
#2
19
For how long do you want to disable the click event listener? One way is to unbind the event listener using jQuery's unbind
http://docs.jquery.com/Events/unbind.
要禁用单击事件侦听器多长时间?一种方法是使用jQuery的unbind http://docs.jquery.com/Events/unbind解绑定事件侦听器。
But it's best-practice not to unbind an event only to rebind it later. Use a boolean instead.
但最好的做法是不解绑定事件,然后再重新绑定。使用一个布尔值。
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: to be safe you should also care about the other ajax completion routines (there are only three: success
, error
, complete
see docs) or else active
might stay false.
编辑:为了安全起见,您还应该关注其他ajax完成例程(只有三个:成功、错误、完成请参阅文档),否则活动可能仍然是错误的。
#3
5
why not disable the button ?Any specific reason that you want to disable this listner alone ? BTB, from your code, I see that you are making an ajax call. SO you specifically want to block user until the call comes back ? If yes, you can try blockUI, a jQuery plugin
为什么不禁用这个按钮?有什么特别的原因使您想要单独禁用这个列表器吗?从您的代码中,我看到您正在进行ajax调用。所以你想要阻止用户直到调用回来?如果是的话,你可以试试jQuery插件blockUI
#4
3
I would setup a global variable to keep track of AJAX requests...
我将设置一个全局变量来跟踪AJAX请求……
var myApp = {
ajax: null
}
And then have this little bit of magic to stop simultaneous requests...
然后有一些魔法来阻止同步请求…
// 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();
}
});
With this approach, you should not have to go back through your code and modify every single one of your AJAX calls. (something I call an "append" solution)
使用这种方法,您不需要返回代码并修改每一个AJAX调用。(我称之为“附加”解决方案)
#5
2
I would use a class eg 'ajax-running'. The click event would only be executed if the clicked element does not have the 'ajax-running' class. As soon you ajax call finishes you can remove the 'ajax-running' class so it can be clicked again.
我将使用一个类“ajax-running”。单击事件只有在单击元素没有“ajax-running”类时才会执行。一旦ajax调用完成,就可以删除“运行ajax”类,以便再次单击它。
$(".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');
});
};
}
});
#6
1
I'd suggest disabling the button, then re-enabling it in your Ajax completion routines (success or failure, remember). If you're worried about the browser not respecting your disabling the button, you can back that with your own flag on the button (e.g., set an attribute called data-disabled
, using the data-
prefix as good practice and to be HTML5 compatible). But barring actually running into a problems with browsers not disabling the button, I'd probably consider that good enough.
我建议禁用该按钮,然后在Ajax完成例程中重新启用它(记住,是成功还是失败)。如果您担心浏览器不尊重您的禁用按钮,您可以在按钮上使用您自己的标志(例如,设置一个名为data-disabled的属性,使用数据前缀作为良好的实践,并与HTML5兼容)。但是,除非实际遇到浏览器无法禁用按钮的问题,否则我可能认为这已经足够了。
#7
1
You could make the action within the click based upon a boolean value. When it's clicked, change the boolean value and uset setTimeout() to change it back after a few seconds. That would effectively limit the user to clicking the button only once every few seconds.
您可以基于布尔值在单击中进行操作。当它被单击时,更改布尔值和uset 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
}
});
#8
1
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);
#9
1
If you are posting via ajax, you can disable the button on click and enable it after the process completes. But if you are posting back, you cannot just disable the button. Disabling the button causes the server side click event not to fire. So just hide the button on click and show user friendly message. The post on how to disable asp.net button on postback helps.
如果您是通过ajax发布的,您可以禁用单击按钮并在流程完成后启用它。但是,如果你是回发,你不能只是禁用按钮。禁用该按钮会导致服务器端单击事件而不触发。所以只要隐藏点击按钮并显示用户友好信息。关于如何在回发中禁用asp.net按钮的文章很有帮助。
#10
0
you could also just hide the button (or the containing div)
还可以隐藏按钮(或包含div)
$(".btnRemove").click(function() {
$(this).hide();
// your code here...
})
and you can just call .show() if you need to display it again.
如果需要再次显示,可以调用.show()。
Also depending on your use case you should consider using a loading overlay instead
同样,根据您的用例,您应该考虑使用加载覆盖
#1
65
There are a lot of ways to do it. For example:
有很多方法可以做到这一点。例如:
$(".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");
});
});
or
或
$(".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);
});
}
We can also use event delegation for clearer code and better performance:
我们也可以使用事件委托来更清晰的代码和更好的性能:
$(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");
});
});
If we don't need to re-enable the handler after it has been executed, then we can use the .one()
method. It binds handlers that are to be executed only once. See jQuery docs: http://api.jquery.com/one
如果我们不需要在处理程序执行之后重新启用它,那么我们可以使用.one()方法。它绑定只执行一次的处理程序。看到jQuery文档:http://api.jquery.com/one
#2
19
For how long do you want to disable the click event listener? One way is to unbind the event listener using jQuery's unbind
http://docs.jquery.com/Events/unbind.
要禁用单击事件侦听器多长时间?一种方法是使用jQuery的unbind http://docs.jquery.com/Events/unbind解绑定事件侦听器。
But it's best-practice not to unbind an event only to rebind it later. Use a boolean instead.
但最好的做法是不解绑定事件,然后再重新绑定。使用一个布尔值。
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: to be safe you should also care about the other ajax completion routines (there are only three: success
, error
, complete
see docs) or else active
might stay false.
编辑:为了安全起见,您还应该关注其他ajax完成例程(只有三个:成功、错误、完成请参阅文档),否则活动可能仍然是错误的。
#3
5
why not disable the button ?Any specific reason that you want to disable this listner alone ? BTB, from your code, I see that you are making an ajax call. SO you specifically want to block user until the call comes back ? If yes, you can try blockUI, a jQuery plugin
为什么不禁用这个按钮?有什么特别的原因使您想要单独禁用这个列表器吗?从您的代码中,我看到您正在进行ajax调用。所以你想要阻止用户直到调用回来?如果是的话,你可以试试jQuery插件blockUI
#4
3
I would setup a global variable to keep track of AJAX requests...
我将设置一个全局变量来跟踪AJAX请求……
var myApp = {
ajax: null
}
And then have this little bit of magic to stop simultaneous requests...
然后有一些魔法来阻止同步请求…
// 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();
}
});
With this approach, you should not have to go back through your code and modify every single one of your AJAX calls. (something I call an "append" solution)
使用这种方法,您不需要返回代码并修改每一个AJAX调用。(我称之为“附加”解决方案)
#5
2
I would use a class eg 'ajax-running'. The click event would only be executed if the clicked element does not have the 'ajax-running' class. As soon you ajax call finishes you can remove the 'ajax-running' class so it can be clicked again.
我将使用一个类“ajax-running”。单击事件只有在单击元素没有“ajax-running”类时才会执行。一旦ajax调用完成,就可以删除“运行ajax”类,以便再次单击它。
$(".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');
});
};
}
});
#6
1
I'd suggest disabling the button, then re-enabling it in your Ajax completion routines (success or failure, remember). If you're worried about the browser not respecting your disabling the button, you can back that with your own flag on the button (e.g., set an attribute called data-disabled
, using the data-
prefix as good practice and to be HTML5 compatible). But barring actually running into a problems with browsers not disabling the button, I'd probably consider that good enough.
我建议禁用该按钮,然后在Ajax完成例程中重新启用它(记住,是成功还是失败)。如果您担心浏览器不尊重您的禁用按钮,您可以在按钮上使用您自己的标志(例如,设置一个名为data-disabled的属性,使用数据前缀作为良好的实践,并与HTML5兼容)。但是,除非实际遇到浏览器无法禁用按钮的问题,否则我可能认为这已经足够了。
#7
1
You could make the action within the click based upon a boolean value. When it's clicked, change the boolean value and uset setTimeout() to change it back after a few seconds. That would effectively limit the user to clicking the button only once every few seconds.
您可以基于布尔值在单击中进行操作。当它被单击时,更改布尔值和uset 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
}
});
#8
1
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);
#9
1
If you are posting via ajax, you can disable the button on click and enable it after the process completes. But if you are posting back, you cannot just disable the button. Disabling the button causes the server side click event not to fire. So just hide the button on click and show user friendly message. The post on how to disable asp.net button on postback helps.
如果您是通过ajax发布的,您可以禁用单击按钮并在流程完成后启用它。但是,如果你是回发,你不能只是禁用按钮。禁用该按钮会导致服务器端单击事件而不触发。所以只要隐藏点击按钮并显示用户友好信息。关于如何在回发中禁用asp.net按钮的文章很有帮助。
#10
0
you could also just hide the button (or the containing div)
还可以隐藏按钮(或包含div)
$(".btnRemove").click(function() {
$(this).hide();
// your code here...
})
and you can just call .show() if you need to display it again.
如果需要再次显示,可以调用.show()。
Also depending on your use case you should consider using a loading overlay instead
同样,根据您的用例,您应该考虑使用加载覆盖