在IE6.0里微软提供对
HTML4.0中定义元素optgroup的支持,不过当我今天使用optgroup时,居然发现其在事件处理上存在bug。该bug影响select元素上的onchange事件,具体表现及处理如下。
我们看一下这个带有optgroup的select事例:
HTML代码及演示脚本如下:
<
html
>
<
head
>
<
title
>optgroup demo
</
title
>
<
meta
name
="author"
content
="birdshome@cnblogs"
/>
</
head
>
<
body
>
<
select
size
="11"
style
="width: 150px"
>
<
optgroup
label
="Group01"
>
<
option
>Option01 Item
</
option
>
</
optgroup
>
<
optgroup
label
="Group02"
>
<
option
>Option02 Item
</
option
>
</
optgroup
>
<
optgroup
label
="Group03"
>
<
option
>Option03 Item
</
option
>
<
option
>Option04 Item
</
option
>
</
optgroup
>
<
optgroup
label
="Group04"
>
<
option
>Option05 Item
</
option
>
<
option
>Option06 Item
</
option
>
<
option
>Option07 Item
</
option
>
</
optgroup
>
</
select
>
<
script
language
="javascript"
>
</
script
>
</
body
>
</
html
>
本演示示例的意图是当select上的选中的条目一旦改变,就执行 一次doChange()方法。你可以点击列表框中的条目并注意一下状态栏,是不是每一次点击都会使数字加一?这是我们希望的效果,同时也说明onchange事件响应是正确的。这时如果你换用键盘上下键来移动列表框中的条目,继续注意状态栏,您会发现什么?状态栏数字的变化没有规律了
,说明doChange()方法不总是在随条目状态改变而执行。仔细观察,会发现如果使用鼠标使在
Group0n这样的条目上下移动时,select元素的onchange事件不会促发。不过此时select元素的selectedIndex属性指示状态是正确的,真是一个烦人的bug
。
怎样修复这个缺陷呢?如果我们使用了optgroup这个元素,为了确保onchange事件不被遗漏,我们同时响应select元素的键盘事件就可以了。为了能监测selectedIndex的改变,我们需要使用select的onkeyup事件(因为这个事件在onchange之后触发),可是如果我们简单的同时注册这两个事件,似乎还是有问题的说。看下面的例子,我们把onkeyup也等于了doChange()方法。
使用键盘操作条目,会在原来正常的地方出问题,就是doChange()方法会被触发两次。上面我们不是说了为什么一定要使用onkeyup监视键盘吗?就是因为onkeyup事件在onchange事件之后执行,所以我们可以利用这个事件触发顺序,自己来检测onchange事件是否已执行。效果如下:
修复bug的脚本代码为:
<
script
language
="javascript"
>
var
g_count
=
0
;
slt.onchange
=
doChange;
slt.onkeyup
=
doKeyup;
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
function
doChange(elmt)
{
elmt.__selectedIndex
=
elmt.selectedIndex;
status
=
g_count
++
;
}
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
function
doKeyup(elmt)
{
if
( elmt.__selectedIndex
!=
elmt.selectedIndex )
{
doChange(elmt);
}
}
</
script
>
我们看一下这个带有optgroup的select事例:
HTML代码及演示脚本如下:
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/edfdf03c6fda40889c005e4f65c6659c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/597adfdc0d744572a7df8658e4709a70.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
本演示示例的意图是当select上的选中的条目一旦改变,就执行 一次doChange()方法。你可以点击列表框中的条目并注意一下状态栏,是不是每一次点击都会使数字加一?这是我们希望的效果,同时也说明onchange事件响应是正确的。这时如果你换用键盘上下键来移动列表框中的条目,继续注意状态栏,您会发现什么?状态栏数字的变化没有规律了
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/08a0c8bad1964e44bf807cfaad847848.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/d43635cd3f4e4c049c382f4a6393874f.gif)
怎样修复这个缺陷呢?如果我们使用了optgroup这个元素,为了确保onchange事件不被遗漏,我们同时响应select元素的键盘事件就可以了。为了能监测selectedIndex的改变,我们需要使用select的onkeyup事件(因为这个事件在onchange之后触发),可是如果我们简单的同时注册这两个事件,似乎还是有问题的说。看下面的例子,我们把onkeyup也等于了doChange()方法。
使用键盘操作条目,会在原来正常的地方出问题,就是doChange()方法会被触发两次。上面我们不是说了为什么一定要使用onkeyup监视键盘吗?就是因为onkeyup事件在onchange事件之后执行,所以我们可以利用这个事件触发顺序,自己来检测onchange事件是否已执行。效果如下:
修复bug的脚本代码为:
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/767216ffb25a498393a019deb461c6b7.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/0f51a99e4bbb4ae0af11d2b95ec60fd7.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/5f0ac2fceb484658b432ec72a036add0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/0f51a99e4bbb4ae0af11d2b95ec60fd7.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/0f51a99e4bbb4ae0af11d2b95ec60fd7.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/b512ceba62184ac3aada416ba3e7a4f0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/5f0ac2fceb484658b432ec72a036add0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/6cc5699791c94c2e95569b6b2b4e6e9a.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article333035/20241017/eb6bb19935724c0485660e7c03a2cd35.gif)
本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。