![扫码关注微信号,访问移动端 扫码关注课课家微信号,访问移动端](/Public/images/qrcodeo_140_140.png)
这里特指下拉框,select。但select有两种形态,由multiple属性决定。在多选形态下,用户按住shift键就能实现多选,但用得不多,主要是占空间。那我们着重说说单选形态及其结构。
下拉框是由多种元素组成,通常我们见过select套着option元素,这中间还能夹一层,optgroup就是对option元素进行分组。option元素里面不能放置其他元素节点,option元素间除了空白或注释节点,也不能放其他东西。
optgroup只是装饰用,对提交数据没有影响,当我们选中某个option元素时,它的selected属性就变成true,之前被选中的元素的selected属性变成false,select元素中selectedIndex的值会变成被选元素的序号(它在所有option元素的位置 )。此外,还有一个鲜为人知的属性selectedOptions,它是对应一个数组,装着被选中的元素,那么它就换成被选中元素。因此DOM操作是一种非常复杂与高消耗的行为,这导致基于虚拟DOM的react库的诞生。减少不必要的DOM操作,就能大幅提高性能。
select的值就是被选中的option元素的值,如果用户定义value属性,那么这值就是option.value,否则就是option的innerHTML,也就是option.text。这当中存在兼容问题,比如有的浏览器会对innerHTML进行两端空白trim操作,有的不会,建议统一使用trim操作。
option.value的提取方法如下:
我们在看看如何动态添加option元素。这有两种方式,1是使用W3C的createElement与appendChild,2是使用new Option及options.add方法。
运行发现标准浏览器如chrome, firefox运行正常,DOM树为
IE(678)全家都呵呵了:
原因在于IE使用innerHTML给select赋值时会根据/^&/(尖括号中间的字母、数字,引号,空格)匹配的字符都干掉,无力吐槽。
我们先来看看Option构造器是怎么用的
除了第一个参数,其他都是可选的,相当于
再看options.add方法。options是select元素的一个数组属性,里面装着所有option元素。add是其上面的一个方法( IE中它也能出现在select元素上),此方法存在兼容问题。
options.add有两种传参方式,第一种要来传入两个元素,第一个是新option元素,第二个是已有的option元素,新元素会插入到旧元素之前。问题出现在第二个参数缺省的情况下:
请注意,在IE6及IE7下请使用不带null参数的add方法,在FF下请使用带null参数的方法,IE8下带不带都可以。
很奇怪为什么一定要加null,我猜测add方法里一定使用了’=== null’来判断第二的参数或者没有对参数数组的长度做验证。
还有一种传参方法,第一个是新option元素,第二个是插入位置,不写默认插入到末尾。
早期IE是不支持传入两个元素,只支持传入元素与插入位置的方式。IE8是两种方式都支持,对于普通浏览器,如果传入的是索引数值,它不会认为是出错,还是会添加在最后。
这是标准DOM API,基本上无所不能。 在以前的IE4中, document只能创建img, area, option三种元素,到了IE5,一般可以编程创建几乎所以元素, 除了frame和iframe。 而且这些新的创建的元素的属性都是可读写的,并且可以编程随意访问。但是你必须得先把他们先回到他们相应的集合中或者当前文档中你才能使用, 否则会报错。
看下一个课题,如何找到可以提交的option元素。因为决定一个option能否提交,除了selected属性外,还有disabled属性,由于disabled属性可能出现在select或optgroup元素上,这问题就复杂了。此外selectedOptions数组属性并不可靠,不是所有浏览器都支持。jQuery在处理这里也花了不少代码。
option还有两个重要的属性,index是返回当前option元素在此select下所有option元素的位置。label是显示其文本,行为有点像text,优化级比text高,但有点兼容性问题。
通常情况下,IE,opera,safari是显示Label1与Label2,而chrome, firefox(即使是4.01的版本)是显示TextContent1与TextContent2,这个古老的bug(见这里) 至今没修复。