很多用户可能会重复单击表单的提交按钮。在涉及信用卡消费时,这就是个问题:因为会导致费用翻番。为此,最常见的解决方案,就是在第一次单击后就禁用提交按钮。只要侦听submit
事件,并在该事件发生时禁用提交按钮即可。以下就是这样一个例子。
//避免多次提交表单
EventUtil.addHandler(form, "submit", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//取得提交按钮
var btn = target.elements["submit-btn"];
//禁用它
btn.disabled = true;
});
共有的表单字段方法
每个表单字段都有两个方法:focus()和 blur(),。其中,focus()方法用于将浏览器的焦点设置到表单字段,即激活表单字段,使其可以响应键盘事件。例如,接收到焦点的文本框会显示插入符号,随时可以接收输入。
EventUtil.addHandler(window, "load", function(event){
document.forms[0].elements[0].focus();
});``
要注意的是,如果第一个表单字段是一个<input>
元素,且其type 特性的值为"hidden"
,那么以上代码会导致错误。另外,如果使用CSS 的display
和visibility
属性隐藏了该字段,同样也会导致错误。
HTML5 为表单字段新增了一个autofocus
属性。在支持这个属性的浏览器中,只要设置这个属性,不用JavaScript 就能自动把焦点移动到相应字段。例如:
<input type="text" autofocus>
为了保证前面的代码在设置autofocus 的浏览器中正常运行,必须先检测是否设置了该属性,如果设置了,就不用再调用focus()
了。
EventUtil.addHandler(window, "load", function(event){
var element = document.forms[0].elements[0];
if (element.autofocus !== true){
element.focus(); console.log("JS focus");
}
});
因为autofocus
是一个布尔值属性,所以在支持的浏览器中它的值应该是true
。(在不支持的浏览器中,它的值将是空字符串。)为此,上面的代码只有在autofocus
不等于true
的情况下才会调用focus()
,从而保证向前兼容。支持autofocus 属性的浏览器有
Firefox 4+、Safari 5+、Chrome 和Opera
9.6。
在默认情况下,只有表单字段可以获得焦点。对于其他元素而言,如果先将其 tabIndex
属性设置为1,然后再调用focus()方法,也可以让这些元素获得焦点。 只有Opera 不支持这种技术。
共有的表单字段事件
change
:对于<input>
和<textarea>
元素,在它们失去焦点且value
值改变时触发;对于<select>
元素,在其选项改变时触发。
</head>
<body>
<form action="">
<input type="text" >
</form>
<script>
var EventUtil = {
addHandler: function(element, type, handler){ //元素注册事件
if (element.addEventListener){
element.addEventListener(type, handler, false);
} else if (element.attachEvent){
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: function(element, type, handler){ //删除元素事件
if (element.removeEventListener){
element.removeEventListener(type, handler, false);
} else if (element.detachEvent){
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
},
getEvent: function(event){
return event ? event : window.event;
},
getTarget: function(event){ //事件实际触发元素跨浏览器
return event.target || event.srcElement;
},
};
var textbox = document.forms[0].elements[0];
EventUtil.addHandler(textbox, "focus", function(event){ //为textbox注册获得焦点事件
event = EventUtil.getEvent(event); //跨浏览器事件对象
var target = EventUtil.getTarget(event); //跨浏览器实际目标元素
if (target.style.backgroundColor != "red"){
target.style.backgroundColor = "yellow";
}
});
EventUtil.addHandler(textbox, "blur", function(event){ //为textbox注册失去焦点事件
event = EventUtil.getEvent(event); //跨浏览器事件对象
var target = EventUtil.getTarget(event); //跨浏览器实际目标元素
if (/[^\d]/.test(target.value)){ //全局查找是否非数字开头
target.style.backgroundColor = "red";
} else {
target.style.backgroundColor = "";
}
});
EventUtil.addHandler(textbox, "change", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if (/[^\d]/.test(target.value)){
target.style.backgroundColor = "red";
} else {
target.style.backgroundColor = "";
}
});
</script>
</body>
通常,可以使用focus 和blur 事件来以某种方式改变用户界面,要么是向用户给出视觉提示,要么是向界面中添加额外的功能(例如,为文本框显示一个下拉选项菜单)。而change 事件则经常用于验证用户在字段中输入的数据。例如,假设有一个文本框,我们只允许用户输入数值。此时,可以利用focus 事件修改文本框的背景颜色,以便更清楚地表明这个字段获得了焦点。可以利用blur 事件恢复文本框的背景颜色,利用change 事件在用户输入了非数值字符时再次修改背景颜色。下面就给出了实现上述功能的代码。
文本框脚本
在HTML 中,有两种方式来表现文本框:一种是使用<input>
元素的单行文本框,另一种是使用<textarea
>的多行文本框。这两个控件非常相似,而且多数时候的行为也差不多。不过,它们之间仍然存在一些重要的区别。要表现文本框,必须将元素的type
特性设置为"text"
。而通过设置size
特性,可以指定文本框中能够显示的字符数。通过value
特性,可以设置文本框的初始值,而maxlength
特性则用于指定文本框可以接受的最大字符数。如果要创建一个文本框,让它能够显示25 个字符,但输入不能超过50 个字符,可以使用以下代码:
相对而言,元素则始终会呈现为一个多行文本框。要指定文本框的大小,可以使用rows和cols
特性。其中,rows
特性指定的是文本框的字符行数,而cols
特性指定的是文本框的字符列数(类似于<inpu>
元素的size
特性)。与<input>
元素不同,<textarea>
的初始值必须要放在textarea>和</textarea>
之间,如下面的例子所示。
<textarea rows="25" cols="5">initial value</textarea>
选择文本
上述两种文本框都支持select()
方法,这个方法用于选择文本框中的所有文本。在调用select()
方法时,大多数浏览器(Opera
除外)都会将焦点设置到文本框中。这个方法不接受参数,可以在任何时候被调用。下面来看一个例子。
var textbox = document.forms[0].elements["textbox1"];
textbox.select();
在文本框获得焦点时选择其所有文本,这是一种非常常见的做法,特别是在文本框包含默认值的时候。因为这样做可以让用户不必一个一个地删除文本。下面展示了实现这一操作的代码。
EventUtil.addHandler(textbox, "focus", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
将上面的代码应用到文本框之后,只要文本框获得焦点,就会选择其中所有的文本。这种技术能够较大幅度地提升表单的易用性。
选择文本
上述两种文本框都支持select()
方法,这个方法用于选择文本框中的所有文本。在调用select()
方法时,大多数浏览器(Opera 除外)
都会将焦点设置到文本框中。这个方法不接受参数,可以在任何时候被调用。下面来看一个例子。
var textbox = document.forms[0].elements["textbox1"];
textbox.select();
在文本框获得焦点时选择其所有文本,这是一种非常常见的做法,特别是在文本框包含默认值的时候。因为这样做可以让用户不必一个一个地删除文本。下面展示了实现这一操作的代码。
EventUtil.addHandler(textbox, "focus", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
});
1. 选择(select)事件
var textbox = document.forms[0].elements["textbox1"];
EventUtil.addHandler(textbox, "select", function(event){
var alert("Text selected" + textbox.value);
});
2. 取得选择的文本
虽然通过**select**
事件我们可以知道用户**什么时候选择了文本
,但仍然不知道用户选择了什么文本。HTML5 通过一些扩展方案解决了这个问题,以便更顺利地取得选择的文本。该规范采取的办法是添加两个属性:selectionStart 和selectionEnd。
这两个属性中保存的是基于0 的数值,表示所选择****文本的范围(**即文本选区开头和结尾的偏移量)。因此,要取得用户在文本框中选择的文本,可以使用如下代码。
function getSelectedText(textbox){
return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
}
因为substring()
方法基于字符串的偏移量执行操作, 所以将selectionStart
和selectionEnd直接传给它就可以取得选中的文本。
IE9+、Firefox、Safari、Chrome 和Opera 都**
支持这两个属性。IE8 及之前版本不支持这两个属性,而是提供了另一种方案。IE8 及更早的版本中有一个document.selection
对象,其中保存着用户在整个文档范围内选择的文本信息;也就是说,无法确定用户选择的是页面中哪个部位的文本。不过,在与select
事件一起使用的时候,可以假定是用户选择了文本框中的文本,因而触发了该事件。要取得选择的文本,首先必须创建一个范围(js高级程序设计第12 章中有),然后再将文本从其中提取出来,如下面的例子所示。
function getSelectedText(textbox){
if (typeof textbox.selectionStart == "number"){
return textbox.value.substring(textbox.selectionStart,
textbox.selectionEnd);
} else if (document.selection){
return document.selection.createRange().text;
}
}
这里修改了前面的函数,包括了在IE 中取得选择文本的代码。注意,调用document.selection时,不需要考虑textbox 参数。
3选择部分文本
HTML5
也为选择文本框中的部分文本提供了解决方案, 即最早由Firefox 引入的
setSelectionRange()
方法。现在除select()
方法之外,所有文本框都有一个setSelectionRange()
方法。这个方法接收两个参数:要选择的第一个字符的索引和要选择的最后一个字符之后的字符的索引(类似于substring()
方法的两个参数)。来看一个例子。
textbox.value = "Hello world!"
//选择所有文本
textbox.setSelectionRange(0, textbox.value.length); //"Hello world!"
//选择前3 个字符
textbox.setSelectionRange(0, 3); //"Hel"
//选择第4 到第6 个字符
textbox.setSelectionRange(4, 7); //"o w"