让表单不再乱跳

为什么会有这个需求呢?因为表单是需要验证的,如果你的表单不需要验证,且只有一个输入框,这篇文章你可以无视了,比如谷哥和度娘的首页就木有这种需求。
 

来说说验证的情况,这需求太普遍了,比如验证两次输入的密码是否一样,用户名是否包含非法字符等,如果不验证表单,这些非法数据就直接提交到服务器了。


<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"/>看起来都很不靠谱

posted @ 2011-10-03 18:20  越己  阅读(3322)  评论(44编辑  收藏  举报