第13章 表单脚本 (三)

来源:互联网 发布:mac废纸篓在哪 编辑:程序博客网 时间:2024/05/29 02:39
 

13.3 选择框脚本

选择框是通过 <select> 和 <option> 元素创建的。为了方便与这个控件交互,除了所有表单字段共有的属性和方法外,HTMLSelectElement 类型还提供了下列属性和方法。

  • add(newOption, relOption): 向控件中插入新 <option> 元素,其位置在指定项 (relOption) 之前。
  • multiple: 布尔值,表示是否允许多项选择;等价于 HTML 中的 multiple 特性。
  • options: 控件中所有 <option> 元素的 HTMLCollection。
  • remove(index): 移除给定位置的选项。
  • selectedIndex: 基于 0 的选中项的索引,如果没有选中项,则值为 -1 。对于支持多选的控件,只保存选中项中第一项的索引。
  • size: 选择框中可见的行数;等价于 HTML 中的 size 特性。
选择框的 type 属性不是 "select-one" ,就是 "select-multiple",这取决于 HTML 代码中有没有 multiple 特性。选择框的 value 属性由当前选中项决定,相应规则如下。
  • 如果没有选中的项,则选择框的 value 属性保存空字符串。
  • 如果有一个选中项,而且该项的 value 特性已经在 HTML 中指定,则选择框的 value 属性等于选中项的 value 特性。即使 value 特性的值是空字符串,也同样遵循此条规则。
  • 如果有一个选中项,但该项的 value 特性在 HTML 中未指定,则选择框的 value 属性等于该项的文本。
  • 如果有多个选中项,则选择框的 value 属性将依据前两条规则取得第一个选中项的值。
以下面的选择框为例:
<select name="location" id="selLocation">
<option value="Sunnyvalue, CA">Sunnyvalue</option>
<option value="Los Angeles, CA">Los Angeles</option>
<option value="Mountain View, CA">Mountain View</option>
<option value="">China</option>
<option>Australia</option>
</select>
如果用户选择了其中第一项,则选择框的值就是 "Sunnyvalue, CA" 。如果文本为 "China" 的选项被选中,则选择框的值就是一个空字符串,因为其 value 特性是空的。如果选择了最后一项,那么由于 <option> 中没有指定 value 特性,则选择框的值就是 "Australia" 。
在 DOM 中,每个 <option> 元素都有一个 HTMLOptionElement 对象表示。为便于访问数据,HTMLOptionElement 对象添加了下列属性:
  • index: 当前选项在 options 集合中的索引。
  • label: 当前选项的标签;等价于 HTML 中的 label 特性。
  • selected: 布尔值,表示当前选项是否被选中。将这个属性设置为 true 可以选中当前选项。
  • text: 选项的文本。
  • value: 选项的值 (等价于 HTML 中的 value 特性)。
其中大部分属性的目的,都是为了方便对选项数据的访问。虽然也可以使用常规的 DOM 功能来访问这些信息,但效率则是比较低的,如下面的例子所示:
var selectbox = document.forms[0].location;
// 不推荐
var text = selectebox.options[0].firstChild.nodeValue;                    // 选项的文本

var value = selecbox.options[0].getAttribute("value");                      // 选项的值

以上代码使用标准 DOM 方法,取得了选择框中第一项的文本和值。可以与下面使用选项属性的代码作一下比较:

var selectbox = document.forms[0].location;

// 推荐

var text = selectbox.options[0].text;                           // 选项的文本

var value = selectbox.options[0].value;                    // 选项的值

在操作选项时,我们建议最好是使用特定于选项的属性,因为所有浏览器都支持这些属性。在将表单控件作为 DOM 节点的情况下,实际的交互方式则会因浏览器而异。我们不推荐使用标准 DOM 技术修改 <option> 元素的文本或者值。

 最后,我们还想提醒读者注意一点:选择框的 change 事件与其他表单字段的 change 事件触发的条件不一样。其他表单字段的 change 事件是在值被修改且焦点离开当前字段时触发,而选择框的 change 事件只要选中了选项就会触发。

不同浏览器下,选项的 value 属性返回什么值也存在差别。但是,在所有浏览器中, value 属性始终等于 value 特性。在未指定 value 特性的情况下,IE 会返回空字符串,而 Safari、Firefox、Chrome 和 Opera 则会返回与 text 特性相同的值。

13.3.1 选择选项

对于只允许选择一项的选择框,访问选中项的最简单方式,就是使用选择框的 selectedIndex 属性,如下面的例子所示:

var selectedOption = selectbox.options[selectbox.selectedIndex];

取得选中项之后,可以像下面这样显示该选项的信息:

var selectedIndex = selectbox.selectedIndex;

var selectedOption = selectbox.options[selectedIndex];

alert("Selected index: " + selectedIndex + "\nSelected text: " + selectedOption.text + "\nSelected value: " + selectedOption.value);

这里,我们通过一个警告框显示了选中项的索引、文本和值。

对于可以选择多项的选择框,selectedIndex 属性就好像只允许选中一项一样。设置 selectedIndex 会导致取消以前的所有选项并选择指定的那一项,而读取 selectedIndex 则只会返回选中项第一项的索引值。

另一种选择选项的方式,就是取得对某一项的引用,然后将其 selected 属性设置为 true 。例如,下面的代码会选中选择框中的第一项:

selectbox.options[0].selected = true;

与 selectedIndex 不同,在允许多选的选择框中设置选项的 selected 属性,不会取消对其他选中项的选择,因而可以动态选中任意多个项。但是,如果是在单选选择框中,修改某个选项的 selected 属性则会取消对其他选项的选择。需要注意的是,将 selected 属性设置为 false 对单选选择框没有影响。

实际上,selected 属性的作用主要是确定用户选择了选择框中的哪一项。要取得所有选中的项,可以循环遍历选项集合,然后测试每个选项的 selected 属性。来看下面的例子:

function getSelectedOptions(selecbox) {

var result = new Array();

var option = null;

for (var i=0, len=selectbox.options.length; i < len; i++){

option = selectbox.options[i];

if (option.selected){

result.push(option);

}

}

return result;

}

这个函数可以返回给定选择框中选中项的一个数组。首先,创建一个将包含选中项的数组,然后使用 for 循环迭代所有选项,同时检测每一项的 selected 属性。如果有选项被选中,则将其添加到 result 数组中。最后,返回包含选中项的数组。下面是一个使用 getSelectedOptions() 函数取得选中项的示例:

var selectbox = document.getElementById("selLocation");

var selectedOptions = getSelectedOptions(selectbox);

var message = "";

for(var i=0, len=selectedOption.length; i < len; i++){

message += "Selected index: " + selectedOptions[i].index + "\nSelected text: " + selectedOptions[i].text + "\nSelected value: " + selectedOptions[i].value + "\n\n";

}

alert(message);

在这个例子中,我们首先从一个选择框中取得了选中项。然后,使用 for 循环构建了一条消息,包含所有选中项的信息: 每一项的索引、文本和值。这种技术适用于单选和多项选择框。

13.3.2 添加选项

可以使用 JavaScript 动态创建选项,并将它们添加到选择框中。添加选项的方式有很多,第一种方式就是使用如下所示的 DOM 方法

var newOption = document.createElement("option");

newOption.appendChild(document.createTextNode("Option text"));

newOption.setAttribute("value", "Option value");

selectbox.appendChild(newOption);

以上代码创建了一个新的 <option> 元素,然后为它添加了一个文本节点,并设置其 value 特性,最后将它添加到了选择框。添加到选择框之后,用户立即就可以看到新选项

第二种方式是使用 Option 构造函数来创建新选项,这个构造函数是 DOM 出现之前就有的,一直遗留到现在。Option 构造函数接受两个参数:文本(text) 和值 (value);第二个参数可选。虽然这个构造函数会创建一个 Object 的实例,但兼容 DOM 的浏览器会返回一个 <option> 元素。换句话说,在这种情况下,我们仍然可以使用 appendChild() 将新选项添加到选择框中。来看下面的例子:

var newOption = new Option("Option text", "Option value");

selectbox.appendChild(newOption);               // 在 IE 中有问题

这种方式在除 IE 之外的浏览器中都可以使用。由于存在 bug ,IE 在这种方式下不能正确设置新选项的文本。

第三种添加新选项的方式是使用选择框的 add() 方法。DOM 规定这个方法接受两个参数:要添加的新选项和将位于新选项之后的选项。如果想在列表的最后添加一个选项,应该将第二个参数设置为 null。在 IE 对 add() 方法的实现中,第二个参数是可选的,而且如果指定,该参数必须是新选项之后选项的索引。兼容 DOM 的浏览器要求必须指定第二个参数,因此要想编写跨浏览器的代码,就不能只传入一个参数。这时候,为第二个参数传入 undefined,就可以在所有浏览器中都将新选项插入到列表的最后了。来看一个例子:

var newOption = new Option("Option text", "Option value");

selectbox.add(newOption, undefined);             // 最佳方案

在 IE 和兼容 DOM 的浏览器中,上面的代码都可以正常使用。如果你想将新选项添加到其他位置 (不是最后一个),就应该使用标准的 DOM 技术和 insertBefore() 方法。

13.3.3 移除选项

与添加选项类似,移除选项的方式也有很多种。首先,可以使用 DOM 的 removeChild() 方法,为其传入要移除的选项,如下面的例子所示:

selectbox.removeChild(selectbox.options[0]);                 // 移除第一个选项

其次,可以使用选择框的 remove() 方法。这个方法接受一个参数,即要移除选项的索引,如下面的例子所示:

selectbox.remove(0);               // 移除第一个选项

最后一种方式,就是将相应选项设置为 null 。这种方式也是 DOM 出现之前浏览器的遗留机制。例如:

selectbox.options[0] = null; // 移除第一个选项

要清楚选择框中所有的项,需要迭代所有选项并逐个移除它们,如下面的例子所示:

function clearSelectbox(selectbox){

for (var i=0, len=selectbox.options.length; i<len; i++) {

selectbox.remove(0);

}

}

这个函数每次只移除框中的第一个选项。由于移除第一个选项后,所有后续选项都会自动向前移动一个位置,因此重复移除第一个选项就可以移除所有选项了。

13.3.4 移动和重排选项

在 DOM 标准出现之前,将一个选择框中的选项移动到另一个选择框中是非常麻烦的。整个过程要涉及从第一个选择框中移除选项,然后以相同的文本和值创建新选项,最后再将新选项添加到第二个选择框中。而使用 DOM 的 appendChild() 方法,就可以将第一个选择框中的选项直接移动到第二个选择框中。我们知道,如果为 appendChild()方法传入一个文档中已有的元素,那么就会先从该元素的父节点中移除它,再把它添加到指定的位置。下面的代码展示了将第一个选择框中的第一个选项移动到第二个选择框中的过程:

var selectbox1 = document.getElementById("selLocation1");

var selectbox2 = document.getElementById("selLocation2");

selectbox2.appendChild(selectbox1.option[0]);

移动选项与移除选项有一个共同之处,即会重置每一个选项的 index 属性。

重排选项次序的过程也十分类似,最好的方式仍然是使用 DOM 方法。要将选择框中的某一项移动到特定位置,最合适的 DOM 方法就是 inertBefore();appendChild() 方法只适用于将选项添加到选择框的最后。要在选择框中向前移动一个选项的位置,可以使用以下代码:

var optionToMove = selectbox.options[1];

selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index -1]]);

以上代码首先选择了要移动的选项,然后将其插入到了排在它前面的选项之前。实际上,第二行代码对除第一个选项之外的其他选项是通用的。类似地,可以使用下列代码将选择框中的选项向后移动一个位置:

var optionToMove = selectbox.options[1];

selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index + 2]);

以上代码适用于选择框中的所有选项,包括最后一个选项。

IE7存在一个页面重绘问题,有时候会导致使用 DOM 方法重排的选项不能马上正确显示。

原创粉丝点击