文本框表单脚本

本文是对 JavaScript 高级程序设计 一书中相关章节的整理,加上自己的理解


在 HTML 中,有两种方式来表现文本框:

  • <input> 定义单行文本框

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

    上面的代码定义了一个单行文本框,可显示25个字符,最大输入长度为50个字符,初始值为“initial value”

  • <textarea> 定义多行文本框

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

    上面的代码定义了一个5行25列,初始值为 “initial value” 的多行文本框

其实,定义初始值,最好还是用 HTML5 中的placeholder 特性,默认样式为灰色字体,输入框获得焦点时,默认值消失,失去焦点时重现:

<input type = "text" size = "25" maxlength = "50" placeholder = "initial value">
<textarea rows = "5" cols = "25" placeholder = "initial value"></textarea>

旧式浏览器可能不支持 placeholder 属性,如果只设置的 placeholder 值,作为提示信息的初始值可能为空。这时我们需要用 value 值来模拟 placeholder 值。我们要在输入框失去焦点时,将其 value 值设为 placeholder 的值,得到焦点时,将 value 设为空,下面是解决方法:

function resetFields(whichform) {
// 用 Modernizr 库检查浏览器是否支持 placeholder 属性,支持的话,返回
if (Modernizr.input.placeholder) return;
// 如果不支持,对传入的表单中的文本控件遍历
for (var i = 0; i < whichform.elements.length; i++) {
var elem = whichform.elements[i];
if (elem.type === "submit" || !elem.placeholder) continue;
elem.onblur = function() {
if (this.value === "") {
this.value = this.placeholder;
}
}
elem.onfocus = function() {
if (this.value === this.placeholder) {
this.value = "";
}
}
elem.blur();
}
}

1. 选择文本

1.1 select() 方法

这个方法用于选中文本框中的所有文本。这个方法不接受参数。
这个方法常用于当一个文本框获得焦点的时候,将其中的文本选中,这样,用户就可以将其中的文本一起删除或修改,看下面的代码:

var textbox = document.forms[0].elements["textbox1"];
textbox.onfocus = function(event) {
target.select();
}

1.2 select 事件

  • 在 IE9+、 Opera、 Firefox、 Chrome 和 Safari 中,当用户选择了文本,并释放鼠标时,该事件被触发
  • IE8 及更早版本,只要用户开始选择该事件就触发,不管鼠标释放不释放
  • 调用 select() 方法时,该事件也会被触发

1.3 取得选中的文本

用 select() 方法,或者用鼠标选择,都只是将文本选中,只是视觉上的,那么怎么才能取得选中的值呢。
下面是跨浏览器的解决方案:

function getSelectedText(textbox) {
// IE9+、 Firefox、 Safari、 Chrome 和 Opera
if (typeof textbox.selectionStart === "number") {
return textbox.value.substring(textbox.selectionStart,
textbox.selectionEnd);
// IE8 及更早的版本,document.selection 对象保存着整个文档内选择的文本
} else if (document.selection) {
// 取得选择的文本,必须先创建一个范围,然后提出文本
return document.selection.createRange().text;
}
}

1.4 选取文本框中的部分文本

上面是当文本选中时同时取得选中的文本,那么怎么样在不选中的时候也能取得其中的部分文本呢。
下面是跨浏览器的方案:

function selectText(textbox, startIndex, stopIndex) {
// IE9+、 Firefox、 Safari、 Chrome 和 Opera
if (textbox.setSelectionRange) {
textbox.setSelectionRange(startIndex, stopIndex);
// IE8 及更早的版本
} else if (textbox.createTextRange) {
var range = textbox.createTextRange();
range.collapse(true);
range.moveStart("character", startIndex);
range.moveEnd("character", stopIndex - startIndex);
range.select();
}
textbox.focus();
}

这个 selectText()函数接收三个参数:要操作的文本框、要选择文本中第一个字符的索引和要选
择文本中最后一个字符之后的索引。
首先,函数测试了文本框是否包含 setSelectionRange()方法。如果有,则使用该方法。
否则,检测文本框是否支持 createTextRange()方法。如果支持,则通过创建范围来实现选择。
最后一步,就是为文本框设置焦点,以便用户看到文本框中选择的文本。

2. 过滤输入

有的输入框中应该只接收特定的字符,比如说电话输入框,那么我们就需要禁止其它字符的输入。我们应该考虑到的情况如下:

  • 这就要用到 keypress 事件,当按下键盘按键的时候获取该按键的编码值,然后再将其转化成对应的按键字符,如果不是数字则禁用。
  • 一般按下插入字符的键会触发 keypress 事件,但有的浏览器的其他按键(方向键,退格键,删除键)也会触发此事件,并且有对应的编码,但是都小于10。
  • 还要考虑 Ctrl + C, Ctrl + V,这些 Ctrl 的组合键。

综合考虑后,跨浏览器的解决方案如下:

var EventUtil = {
// 添加事件、获取事件对象和事件目标等属性的跨浏览器方案,在前面文章写过
// 这里添加一个获取按键编码的方法
getCharCode: function(event) {
// IE9、 Firefox、 Chrome 和 Safari
if (typeof event.charCode === "number") {
return event.charCode;
// IE8 及之前版本和 Opera
} else {
return event.keyCode;
}
}
}
// 为文本框添加 keypress 事件
EventUtil.addHandler(textbox, "keypress", function(event) {
// 获取事件对象,和按键编码
event = EventUtil.getEvent(event);
var charCode = EventUtil.getCharCode(event);
// 如果得到的编码转换成字符不是数字字符,并且编码数大于9,并且不包括 Ctrl 键,则禁用按键
if (!/\d/.test(String.fromCharCode(charCode)) && charCode > 9 && !event.ctrlKey) {
EventUtil.preventDefault(event);
}
});

3. 自动切换焦点

当输入字符数量等于输入框设置的最大字符数时,自动将焦点切换到下一个输入框,来提高易用性。

<input type="text" name="tel1" id="txtTel1" maxlength="3">
<input type="text" name="tel2" id="txtTel2" maxlength="3">
<input type="text" name="tel3" id="txtTel3" maxlength="4">
<script type="text/javascript">
function tabForward(event) {
event= EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
// 如果当前文本输入框中字符数到达最大设定值
if (target.value.length === target.maxlength) {
// 获取当前控件的表单
var form = target.form;
// 对表单中控件进行遍历
for (var i = 0; i < form.elements.length; i++) {
// 遍历到目标控件
if (form.elements[i] === target) {
// 检查是否有下一个控件
if (form.elements[i+1]) {
// 如果有下一个控件,将焦点移入
form.elements[i+1].focus();
}
// 不再遍历下一个控件
return;
}
}
}
}
var textbox1 = document.getElementById("txtTel1");
var textbox2 = document.getElementById("txtTel2");
var textbox3 = document.getElementById("txtTel3");
EventUtil.addHandler(textbox1, "keyup", tabForward);
EventUtil.addHandler(textbox2, "keyup", tabForward);
EventUtil.addHandler(textbox3, "keyup", tabForward);
</script>