我正在使用按钮通过Ajax提交数据。我正在使用jQuery来禁用和启用按钮。这是为了防止“按钮混合”,用户可以恶意或无意地发出多个请求。
是否有一种“元素无关”的方法来防止jQuery中的这种行为?例如,假设我想使用锚点而不是按钮来提交数据。我可以禁用一个按钮;但据我所知,你无法禁用锚点。
以下是我现在正在做的事情:(请注意我删除了一些不必要的代码以缩短代码)
$('.fav .button').click(function() {
$.ajax({
context: this,
dataType: 'json',
beforeSend: function() {
// Toggle state; disable button to prevent button mashing
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", true);
},
error: function() {
// Rollback state and re-enable button on error
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", false);
},
success: function(response) {
if (response.result == "success") {
$(".fav .button").attr("disabled", false);
}
else {
// Rollback state; re-enable button
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", false);
}
}
});
return false;
});
HTML:
<input class="button" type="button" value="">
答案 0 :(得分:6)
当然,最好的方法是在服务器端优雅地处理它。
也就是说,你可以使用jQuery中的data storage methods来存储一个值,表明它已被点击,并用它来确定用户是否已经点击/按下了按钮。每个选择器都会存储这些值,因此您可以在任何选项上进行设置。
$("a").click(function(e) {
e.preventDefault();
if (!$(this).data('isClicked')) {
var link = $(this);
// Your code on successful click
// Set the isClicked value and set a timer to reset in 3s
link.data('isClicked', true);
setTimeout(function() {
link.removeData('isClicked')
}, 3000);
} else {
// Anything you want to say 'Bad user!'
}
});
好处是您不会阻止用户点击任何其他内容,因为它是每个元素的解决方案。在您的情况下,您可能希望在成功函数中执行link.removeData
。
工作示例:http://jsfiddle.net/jonathon/ke8Az/(请注意,如果您尝试在3秒内再次点击,则会显示“请稍候”,但您仍然可以点击其余部分)
注意:这只是一个客户端解决方案。如果他们安装了JavaScript,则仅。除非您在服务器端处理它,否则用户可以恶意发送多个请求。这只是帮助“不知不觉”的部分。
答案 1 :(得分:2)
在ajax调用之前,您可以取消绑定单击对象上的click事件,然后在success / error方法中重新绑定click事件。
通过这种方式,他们可以根据需要对按钮进行混搭,但在通话完成之前,它不会连接点击。
答案 2 :(得分:1)
您可以执行以下操作:
您必须根据需要自定义变量名称,并且需要找到一种方法将变量保持在正确的范围内,但这并不困难。
答案 3 :(得分:1)
停止您描述的行为的最佳和唯一方法是在服务器端。
答案 4 :(得分:1)
您也可以使用debounce
仅注册一次。 underscore.js和lodash.js都提供了这种方便的方法。
这里有fiddle来演示这个概念。使用lazyClick
,您可以双击/三次点击链接,但事件处理程序只会被触发一次。
var lazyClick = _.debounce(onclickHandler, 500);
function onclickHandler(e){
e.preventDefault();
console.log('clicked');
}
$(function(){
// uncomment this and you will see double clicks are being registered.
//$('#btn').click(onclickHandler);
// with debounce, only one click will be registered
$('#btn').click(lazyClick);
});