让表单不再乱跳
为什么会有这个需求呢?因为表单是需要验证的,如果你的表单不需要验证,且只有一个输入框,这篇文章你可以无视了,比如谷哥和度娘的首页就木有这种需求。
来说说验证的情况,这需求太普遍了,比如验证两次输入的密码是否一样,用户名是否包含非法字符等,如果不验证表单,这些非法数据就直接提交到服务器了。
<input type="submit"/>的click事件和form的submit事件
提交表单的最后一步是表单的submit事件,如果有<input type="submit"/>,那它的click事件也会触发,触发顺序是click -> submit
<form onsubmit="alert('submit')"> <input type="text"/> <input type="submit" value="提交" onclick="alert('click')"/> </form>
IE10, Chrome14, FF7, Safari5, Opera11表现一致。
那么为了确保提交前进行验证,可在submit事件处理函数中进行处理。
var temp = form.onsubmit; form.onsubmit = function(){ alert('进行验证'); if(typeof temp === 'function'){ temp(); } }
还有更极端的,如果你压根就想废掉回车这玩意,那就让表单监听键盘事件吧
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript"> window.onload = function(){ var form = document.getElementsByTagName('form')[0], temp = form.onsubmit; form.onsubmit = function(){ alert('进行验证'); if(typeof temp === 'function'){ temp(); } } form.onkeydown = function(e){ e = e || window.event; if(e.keyCode === 13){ alert('拦截回车') if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } } } } </script> </head> <body> <form onsubmit="alert('submit')"> <input type="text"/> <input type="submit" value="提交" onclick="alert('click')"/> </form> </body> </html>
打印结果:
Chrome14:拦截回车 - click - 进行验证 - submit
Firefox7:click - 进行验证 - submit - 拦截回车
IE10, Safari5, Opera11:拦截回车
可以发现FF首先触发的不是keydown事件,下面会继续这个问题,这里先插一个知识点:阻止默认行为。
上例中,阻止默认事件我是这么写的
if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; }
之前我很喜欢用return false,搜了下,发现return false也不是万能的,有个别的兼容性问题,我截个图吧
来源: http://www.cnblogs.com/idche/archive/2010/11/13/1876604.html
说明:keydown * 2表示绑定了两次keydown事件,其它同理
好了,继续往下说,chrome和FF到底是怎么回事呢?
这次我换成监听表单的keydown 和 keyup事件:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript"> window.onload = function(){ var form = document.getElementsByTagName('form')[0], temp = form.onsubmit; form.onsubmit = function(){ alert('进行验证'); if(typeof temp === 'function'){ temp(); } } form.onkeydown = stopEnter; form.onkeyup = stopEnter; function stopEnter(e){ e = e || window.event; if(e.keyCode === 13){ alert(e.type + ' 拦截回车') if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } } }; } </script> </head> <body> <form onsubmit="alert('submit')"> <input type="text"/> <input type="submit" value="提交" onclick="alert('click')"/> </form> </body> </html>
结果如下:
Chrome14:keydown拦截回车 - click - 进行验证 - submit
Firefox 7:keyup拦截回车 - click - 进行验证 - submit - keydown拦截回车
IE10, Safari5, Opera11:keydown拦截回车
这回第一个触发的都是键盘事件,但是chrome和FF还是把整个过程都走完了,我就奇怪了,那段阻止默认行为的代码怎么就没用呢?坑爹啊!!!
我发现我有点钻牛角尖了,其实这个问题的实质是两种需求:
1. 需要用回车提交表单 (比如只有一个输入框,且需要验证输入内容)
2. 完全禁止回车 (比如有多个输入框,用户只能点最后的提交按钮,而不能在中间直接回车)
对于1, 我最开始那段代码已经可以解决需求
var temp = form.onsubmit; form.onsubmit = function(){ if(验证通过){ if(typeof temp === 'function'){ temp(); } }else{ return false; } }
对于2,刚才说了大半天,chrome和FF实在不给面子,我也想不到更好的办法,找一个折衷的吧,稍微改改HTML代码,先看下图:
来源:http://www.blueidea.com/tech/web/2009/6390.asp
根据上图第二条,如果你的表单只有一个<input type="text"/>,一个?!!! 请看需求1的代码好吧,绕来绕去伤不起啊。
对于有多个输入框的情况,如果你的表单还有type="submit"这种东西,全给删了吧,亲!
根据上图第三条,我强烈推荐按钮都用<a>,表单元素的按钮,不管是<button>还是<input type="button"/>看起来都很不靠谱