之前的做法 就是把按钮给禁用掉,
突然 想起文本框里敲回车 还是会提交表单。
现在打算用一变量来标记是否已经点击了提交。
我想知道的是 还有没别的 更优雅的方法?
http://underscorejs.org/#once
我的解决方式是: 发送前判断按钮的状态,判断 data-state 属性值 是否为1 如果为1,return false; 不为1,则设置这个属性值为1,然后进行ajax操作,在ajax返回结果后,再把该属性值改为0.
难道是我理解错了题意,这个不就是一句return false就能解决的问题吗?
$('form').submit(function(){//当表单被提交时,触发
$.ajax({
// do somethings
});
return false; //靠return false来阻止html的表单动作,让所有的表单动作都交给JS来处理。
});
当然,还可以通过event.preventDefault()也能阻止表单默认的提交动作
用一个变量加锁
var lock = false;
执行Ajax的事件起初处判断
if (lock) {return;}
在Ajax发送前
lock = true;
在Ajax返回或错误后的回调函数中
lock = false;
如果你觉得无效化按钮挺优雅的话,那可以把整个表单都无效化加上 disabled
,就不担心回车的问题了,嫌麻烦还有简单的。
写一个loading
.loading {
position: absolute;
z-index: 10000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: url(...) center center;
}
然后像上面的变量一样的,加锁时放入这个loading的标签,比如
$('form').append($('div').addClass('loading'));
回调后解锁时删除它
$('form').find('.loadding').detach();
如果只是前端方面,除了给button加上disable,加标记,还可以设置cookie,方法很多 后台方法给session加标记,再变态点的 直接插到数据库里..
可以使用jquery的 bind 和unbind方法很好解决的
在开发中,我一般按两个方法: 一是阻止回车提交表单,具体方法是 onkeydown="return false;" 二是提交之后跳转页面
提交发生后,直接禁用输入框和提交按钮就行了。
<form id="search">
<input type="text">
<input type="submit">
</form>
<script>
$("#search").bind("submit", function(e) {
e.preventDefault();
$("input").attr({"disabled": "disabled"});
// ajax code here
//....
});
</script>
我觉得,你弄错了问题的重心。 首先,在前端上的修改并不能阻止用户的提交,这个世界上有很多专门用来修改页面的工具,Chrome?FireBug? 那么你真正的工作量应该是在后段。 其次,这时候才开始考虑前端的屏蔽,那么就Easy多了,随便用一个什么方式,关了submit就可以了啊,不需要想那么多的。
==========================================================================
用户分两种: 普通用户:你随便设置一个什么障碍,他们就得乖乖的等着,等到你的按钮可以点的时候。 开发者用户:对于他们来说,他们直接面对你的服务器。他们可能会copy你的数据,然后直接发送给你的服务器,每秒上百次甚至更多。也就是说,理论上你的前段并不在你的控制下。
@Tychio 的回答一句很好的回答了如何再前端防止重复提交了,我补充一个在后端判断的逻辑。可以在form里面添加一个隐藏域,值是随机的。如果有连续两次的请求值相同,说明是重复提交了,后面的提交可以舍弃。
重复提交是你代码逻辑的问题吧。怎么解决只有你自己知道。
不好听
之前的做法 就是把按钮给禁用掉,
突然 想起文本框里敲回车 还是会提交表单。
我一般也是采用这种方式,但不知你的实现手法是否和我的一样。
『文本框里敲回车』实际是触发form表单里的<button type="submit">按钮,你可以为这个button添加disabled属性:
<button type="submit" disabled>
这样就不会触发form表单的submit事件了。
如果你是绑定了这个按钮的click事件,那可以检测它是否有disabled属性,有的话直接return就好了。