第13章 表单脚本 (二)

 

13.2 文本框脚本

在 HTML 中,有两种方式来表现文本框:一种是使用 <input> 元素的单行文本框,另一种是使用 <textarea> 的多行文本框。这两个控件非常相似,而且多数时候的行为也差不多。不过,它们之间仍然存在一些重要的区别。

要表现文本框,必须将 <input> 元素的 type 特性设置为 "text" 。而通过设置 size 特性,可以指定文本框中能够显示的字符数。通过 value 特性,可以设置文本框的初始值,而 maxlength 特性则用于指定文本框可以接受的最大字符数。如果要创建一个文本框,让它能够显示 25 个字符,但输入不能超过 50 个字符,可以使用以下代码:

<input type="text" size="25" maxlength="50" value="initial value">

相对而言,<textarea> 元素则始终会呈现为一个多行文本框。要指定文本框的大小,可以使用 rows 和 cols 特性。其中,rows 特性指定的是文本框的字符行数,而 cols 特性指定的是文本框的字符列数 (类似于 <input> 元素的 size 特性)。与 <input> 元素不同,<textarea>的初始值必须要放在 <textarea> 和 </textarea> 之间,如下面的例子所示:

<textarea rows="25" cols="5">initial value</textarea>

另一个与 <input> 的区别在于,不能在 HTML 中给 <textarea> 指定最大字符数。

无论这两种文本框在标记中有什么区别,但它们都会将用户输入的内容保存在 value 属性中。可以通过这个属性读取和设置文本框的值,如下面的例子所示:

var textbox = document.form[0].elements["textbox1"];

alert(textbox.value);

textbox.value = "Some new value";

我们建议读者像上面这样使用 value 属性读取或设置文本框的值,不建议使用标准的 DOM 方法。换句话说,不要使用 setAttribute() 设置 <input> 元素的 value 特性,也不要去修改 <textarea> 元素的第一个子节点。原因很简单:对 value 属性所作的修改,不一定会反映在 DOM 中。因此,在处理文本框的值时,最好不要使用 DOM 方法。

13.2.1 选择文本

上述两种文本框都支持 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) 事件

与 select() 方法对应的,是一个 select 事件。在选择了文本框中的文本时,就会触发 select 事件。不过,到底什么时候触发 select 事件,还会因浏览器而异。在 Opera、Firefox、Chrome 和 Safari 中,只有用户选择了文本 (而且要释放鼠标),才会触发 select 事件。而在 IE 中,只要用户选择了一个字母 (不必释放鼠标),就会触发 select 事件。另外,在 IE 、Firefox 和 Opera 中,也会在调用 select() 方法时触发 select 事件;但在 Safari 和 Chrome 中则不会。因此,要想编写跨浏览器的代码,必须得像下面这样手工取得对事件目标的引用:

var textbox = document.forms[0].elements["textbox1"];

EventUtil.addHandler(textbox, "select", function(event) {

var target = document.forms[0].elements["textbox1"];

alert("Text selected");

});

这里,通过在事件处理程序中重新获取对文本框的引用,可以避免在跨浏览器时出现问题。

Firefox 2 中存在 bug,其 select 事件的目标始终是 document。Firefox 3 修改了这个 bug 。

2.取得选择的文本

虽然通过 select 事件我们可以知道用户什么时候选择了文本,但仍然不知道用户选择了什么文本。没有任何标准就如何取得选择的文本作出规定,因此就出现了一些事实标准。其中,Firefox 的方案最受开发人员认可。Firefox 为文本框添加了两个属性: selectionStart 和 selectionEnd 。这两个属性中保存的是基于 0 的数值,表示所选择文本的范围。因此,要取得用户在文本框中选择的文本,可以使用如下代码:

function getSelectedText(textbox){

return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);

}

Firefox、Safari、Chrome 和 Opera 都支持这两个属性。IE 不支持这两个属性,而是提供了另一种方案。

IE有一个 document.selection 对象,其中保存着用户在整个文档范围内选择的文本信息;也就是说,无法确定用户选择的是页面中哪个部位的文本。不过,在与 select 事件一起使用的时候,可以假定是用户选择了文本框的文本,因而触发了该事件。要取得选择的文本,首先必须建一个范围 (第11 章讨论过),然后再将文本从其中提取出来,如下面的例子所示:

function getSelectedText (textbox) {

if (document.selection) {

return document.selection.createRange().text;

} else {

return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);

}

}

这里修改了前面的函数,包括了在 IE 中取得选择文本的代码。注意,调用 document.selection 时,不需要考虑 textbox 参数。

13.2.2 过滤输入

我们经常会要求用户在文本框中输入特定的数据,或者输入特定格式的数据。例如,必须包含某些字符,或者必须匹配某种模式。由于文本框在默认情况下没有提供多少验证数据的手段,因此必须使用 JavaScript 来完成此类过滤输入的操作。而综合运用事件和 DOM 手段,就可以将普通的文本框转换成能够理解用户输入数据的功能型控件。

1.屏蔽字符

有时候,我们需要用户输入的文本中包含或不包含某些字符。例如,电话号码中不能包含非数值字符。如前所述,响应向文本框中插入字符操作的是 keypress 事件。因此,可以通过阻止这个事件的默认行为来屏蔽此类字符。在极端的情况下,可以通过下列代码屏蔽所有按钮操作:

EventUtil.addHandler(textbox, "keypress", function(event){

event = EventUtil.getEvent(event);

EventUtil.preventDefault(event);

});

运行以上代码后,由于所有按键操作都将被屏蔽,结果会导致文本框变成只读的。如果只想屏蔽特定的字符,则需要检测 keypress 事件对应的字符编码,然后再决定如何响应。例如,下列代码只允许用户输入数值:

EventUtil.addHandler(textbox, "keypress", function(event){

event = EventUtil.getTarget(event);

var target = EventUtil.getTarget(event);

var charCode = EventUtil.getCharCode(event);

if (!/\d/.test(String.fromCharCode(charCode))) {

EventUtil.preventDefault(event);

}

});

在这个例子中,我们使用 EventUtil.getCharCode() 实现了跨浏览器取得字符编码。然后,使用 String.fromCharCode() 将字符编码转换成字符串,再使用正则表达式 /\d/ 来测试该字符串,从而确定用户输入的是不是数值。如果测试失败,那么就使用 EventUtil.preventDefault() 屏蔽按键事件。结果,文本框就会忽略所有输入的非数值。

虽然理论上只应该在用户按下字符键时才触发 keypress 事件,但有些浏览器也会对其他键触发此事件。Firefox 和 Safari(3.1版本以前) 会对向上键、向下键、退格键和删除键触发 keypress 事件;Safari 3.1 及更新版本则不会对这些键触发 keypress 事件。这意味着,仅考虑到屏蔽不是数值的字符还不够,还要避免屏蔽这些极为常用和必要的键。所幸的是,要检测这些键并不困难。在 Firefox 中,所有由非字符键触发的 keypress 事件对应的字符编码为 0 ,而在 Safari 3 以前的版本中,对应的字符编码全部为 8 。为了让代码更通用,只要不屏蔽那些字符编码小于 10 的键即可。故而,可以将上面的函数重写成如下所示:

EventUtil.addHandler(textbox, "keypress", function(event){

event = EventUtil.getEvent(event);

var target = EventUtil.getTarget(event);

var charCode = EventUtil.getCharCode(event);

if (!/\d/.test(String.fromCharCode(charCode)) && charCode > 9){

EventUtil.preventDefault(event);

}

});

这样,我们的事件处理程序就可以适用所有浏览器了,即可以屏蔽非数字字符,但不屏蔽那些也会触发 keypress 事件的基本按键。

除此之外,还有一个问题需要处理:复制、粘帖及其他操作还要用到 Ctrl 键。在除 IE 之外的所有浏览器中,前面的代码也会屏蔽 Ctrl+C、Ctrl+V,以及其他使用 Ctrl 的组合键。因此,最后还要添加一个检测条件,以确保用户没有按下 Ctrl 键,如下面的例子所示:

EventUtil.addHandler(textbox, "keypress", function(event){

event = EventUtil.getEvent(event);

var target = EventUtil.getTarget(event);

var charCode = EventUtil.getCharCode(event);

if (!/\d/.test(String.fromCharCode(charCode)) && charCode > 9 && !event.ctrlKey){

EventUtil.preventDefault(event);

}

});

经过最后一点修改,就可以确保文本框的行为完全正常了。在这个例子的基础上加以修改和调整,就可以将同样的技术运用用放过和屏蔽任何输入文本框的字符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值