选择框脚本

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


选择框是通过 <select><option> 两个元素来创建的。

1. 属性和方法

1.1 select 元素

除了通用的一些属性和方法外,<select> 还具有如下属性和方法:

属性/方法 说明
options 当前选择框内包含的所有选项的 HTMLCollection 集合
size 选择框呈现的选项的数目
multiple 是否允许多选 true/false
add(new, rel) 插入新元素,并指定后面的元素
remove(index) 移除给定位置的选项
selectedIndex 选中项的索引

另,选择框的 type 属性值不是 selection-one 就是 selection-multiple,取决于 HTML 代码中有没有 multiple 特性

<form id="myForm" action="index.html" method="post">
<select name="city" size = "5" multiple = "multiple">
<option value="0北京">北京</option>
<option value="1上海">上海</option>
<option value="2广州">广州</option>
<option value="">深圳</option>
<option>杭州</option>
</select>
</form>
<script type="text/javascript">
var form = document.getElementById("myForm");
var selection = form.elements["city"];
var options = selection.options; // HTMLOptionCollection
var firstOpt = options[0]; // HTMLOptionElement
var type = selection.type; // selection-multiple
</script>

1.2 option 元素

除了通用的一些属性和方法外,<option> 还具有如下属性和方法:

属性/方法 说明
index 当前选项的索引值
value 当前选项的值(最好用这种方法代替 DOM 去获取选项节点的值
text 当前选项的文本(最好用这种方法代替 DOM 去获取选项节点的文本值
label 当前选项的标签
selected 当前选项是否被选中 true/false
// 接上面例子中的代码
alert(firstOpt.text); // 北京
alert(firstOpt.value); // 0北京
alert(options[3].value); // ""
alert(options[4].value); // 没有 value 特性时,IE 返回空字符串,其他浏览器返回 text 特性值

:其他表单字段的 change 事件是在值被修改并失去焦点离开当前焦点时发生,而选择框的 change 事件是只要选中了选项就会发生。

2. 选择选项

2.1 单选框

对于单选框,访问选中项的最简单方法是利用 select 元素的 selectedIndex 属性,该属性保存了被选中选项在选择框内的索引值。

var selectedOpt = selectBox.options[selectBox.selectedIndex];
alert("Selected index: " + selectBox.selectedIndex +
"\nSelected text: " + selectedOpt.text +
"\nSelected value " + selectedOpt.value);

2.2 多选框

对于多选框,selectedIndex 只保存了选中项的第一项。为了访问所有选中项中的信息,我们需要用到 <option> 元素中 selected 属性:

function getSelectedOpt(whichSelect) {
var result = new Array();
var option = null;
for (var i = 0, len = whichSelect.options.length; i < len; i++) {
option = whichSelect.options[i];
if (option.selected) {
result.push(option);
}
}
return result;
}

上面定义了一个 getSelectedOpt 函数,这个函数返回一个数组,这个数组中包含选择框中所有被选中的选项节点对象。

然后我们可以利用下面这个函数提取每个选中项的信息:

var selectBox = document.getElementById("mySelect");
var selectedOptions = getSelectedOpt(selectBox);
var message = "";
for (var i = 0; i < selectedOptions.length; i++) {
message += "Selected index: " + selectedOptions[i].index +
"\nSelected text: " + selectedOptions[i].text +
"\nSelected value " + selectedOptions[i].value + "\n\n")
}
alert(message);

3. 添加选项

3.1 创建选项

创建选项有两种方法:一种是 DOM 的标准创建法;另一种是用 Option 构造函数创建。

// DOM 标准创建法
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("武汉"));
newOption.setAttribute("value", "6武汉");
selectBox.appendChild(newOption);
// Option 构造函数创建
var newOption = new Option("option text", "option value");
selectionBox.appendChild(newOption);

虽然构造函数会创建一个 option 实例,但在兼容 DOM 的浏览器中会返回一个 <option> 元素节点。所以,也可以用 DOM 的方法去插入到文本中。

3.2 添加到选择框

上面提到了,可以用 new 操作符去创建一个选项实例,并且在兼容 DOM 的浏览器中可以将其作为一个节点用 DOM 的方式去插入到文本中。但是,IE8及其以下版本不支持 DOM 标准。

这时,我们需要用到 select 元素的 add() 方法(DOM 标准的方法,IE 也支持)这方法接收两个参数,分别是新选项和位于新选项之后的选项。

DOM 规定,第二个参数必填,如果后面没有选项,即新选项添加到最后,那么设为 null。
IE 中,第二个参数必须是下一个选项的索引值,且可以不填,填入 null 出错。

那么,就导致只有 将新选项插入最后,才能跨浏览器实现,兼容方法是将第二个参数设为 undefined:

selectBox.add(newOption, null); // IE 出错
selectBox.add(newOption, undefined); // 兼容

如果想把新创建的选项插入到其它位置(不是最后一个),就应该使用 DOM 标准的方法,如 insertBefore() 方法。

4. 移除选项

移除选项一般有三种方法:

  • 第一种是DOM 的 removeChild() 方法
  • 第二种是 select 元素的 remove() 方法,接受一个参数为选项的索引值
  • 第三种是将该选项赋值为 null
selectBox.removeChild(selectBox.options[0]);
selectBox.remove(0);
selectBox.options[0] = null;

5. 移动选项

  1. appendChild() 方法
    这个方法将一个选项从原来的位置删除,并插入到一个选择框的末尾。

    var selectBox1 = document.getElementById("mySelect1");
    var selectBox2 = document.getElementById("mySelect2");
    // 将 selectBox1 中的第二个选项移动到 selectBox2 的末尾
    selectBox2.appendChild(selectBox1.options[1]);
  2. insertBefore() 方法
    appendChild() 方法只适合将一个选项移动到一个选择框的末尾,如果想移动到其它位置,那么就要用到 insertBefore() 方法,这个方法将一个选项插入到另一个选项前面:

    var optionToMove = selectBox.options[2];
    selectBox.insertBefore(optionToMove, selectBox.options[optionToMove.index - 1]);

    上面的代码将第三位的选项移动到了第二位,原来第二位的选项被挤到了第三位。

6. 级联下拉选择器的实现

// HTML 代码
// <form name = "myForm">
// <select name = "province">
// <option>请选择省份</option>
// </select>
//
// <select name = "city">
// <option>请选择城市</option>
// </select>
// </form>
// 数据
var provinces = [
{text: "1. 广东", value: "1"},
{text: "2. 河南", value: "2"}
];
var cities = {
1: [
{text: "1.1 广州", value: "1.1"},
{text: "1.2 深圳", value: "1.2"},
{text: "1.3 东莞", value: "1.3"},
{text: "1.4 中山", value: "1.4"},
{text: "1.5 惠州", value: "1.5"},
{text: "1.6 珠海", value: "1.6"}
],
2: [
{text: "2.1 郑州", value: "2.1"},
{text: "2.2 洛阳", value: "2.2"},
{text: "2.3 安阳", value: "2.3"},
{text: "2.4 信阳", value: "2.4"},
{text: "2.5 新乡", value: "2.5"}
]
};
// 根据数据列表填充选择器,第一个参数是要填充的选择框节点,第二个参数是要填入的数据数组
function fillSelect(select, dataList) {
// 对选择框内的选项遍历,并删除全部选项(!!!!!没有完全删除,留下了一个作为默认值!!!!!)
for (var i = select.options.length-1; i > 0; i--) {
select.remove(i);
}
// 对传入的数据进行遍历,提取每一项数据中的信息,创建一个选项并插入选择框
dataList.forEach(function(data) {
var option = new Option(data.text, data.value);
select.appendChild(option);
});
}
var provinceSelect = document.forms["myForm"]["province"];
var citySelect = document.forms["myForm"]["city"];
// 填充省份选择框
fillSelect(provinceSelect, provinces);
// 为省份选择框绑定 change 事件
provinceSelect.addEventListener(
"change", function(event) {
// 根据此时的选择框中的值来提取城市数据中对应的数组
var value = event.target.value,
list = cities[value] || [];
// 将提取的数组填入到城市选择框中
fillSelect(citySelect, list);
}
);