在使用optgroup时遇到的缺陷与修复

    在IE6.0里微软提供对 HTML4.0中定义元素optgroup的支持,不过当我今天使用optgroup时,居然发现其在事件处理上存在bug。该bug影响select元素上的onchange事件,具体表现及处理如下。

    我们看一下这个带有optgroup的select事例: 
   
  • <script language="javascript" type="text/javascript"> var g_count = 0; var slt = document.getElementsByTagName('SELECT')[0]; slt.onchange = doChange; function doChange() { status = g_count++; } </script>

        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()方法。
       
  • <script language="javascript" type="text/javascript"> var g_count2 = 0; function doChange2() { status = g_count2++; } </script>  

        使用键盘操作条目,会在原来正常的地方出问题,就是doChange()方法会被触发两次。上面我们不是说了为什么一定要使用onkeyup监视键盘吗?就是因为onkeyup事件在onchange事件之后执行,所以我们可以利用这个事件触发顺序,自己来检测onchange事件是否已执行。效果如下:
       
  • <script language="javascript" type="text/javascript"> var g_count3 = 0; function doChange3(elmt) { elmt.__selectedIndex = elmt.selectedIndex; status = g_count3++; } function doKeyup3(elmt) { if ( elmt.__selectedIndex != elmt.selectedIndex ) { doChange3(elmt); } } </script>  
        
        修复bug的脚本代码为:
    < script  language ="javascript" >
    var g_count = 0;
    slt.onchange 
    = doChange;
    slt.onkeyup 
    = doKeyup;

    function doChange(elmt)
    {
        elmt.__selectedIndex 
    = elmt.selectedIndex;
        
        status 
    = g_count++;
    }


    function doKeyup(elmt)
    {
        
    if ( elmt.__selectedIndex != elmt.selectedIndex )
        
    {
            doChange(elmt);
        }

    }

    </ script >

  •  
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值