让表单不再乱跳
为什么会有这个需求呢?因为表单是需要验证的,如果你的表单不需要验证,且只有一个输入框,这篇文章你可以无视了,比如谷哥和度娘的首页就木有这种需求。
来说说验证的情况,这需求太普遍了,比如验证两次输入的密码是否一样,用户名是否包含非法字符等,如果不验证表单,这些非法数据就直接提交到服务器了。
<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(); } } |
还有更极端的,如果你压根就想废掉回车这玩意,那就让表单监听键盘事件吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <! 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事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <! 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"/>看起来都很不靠谱
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库