IE11下select选项排序后首项无法选中的技术问题咨询
看起来你碰到了IE11特有的DOM操作兼容性坑——我之前也遇到过类似的问题!单独跑代码片段都正常,组合起来就罢工,这种情况在旧IE里真的很让人头疼。
问题场景回顾
你的代码功能是把select控件的选项按字母排序,然后选中首项。在Chrome和Firefox里一切正常,但IE11里排序成功了,可首项('five')就是选不上。更奇怪的是,控制台单独执行选中代码又能生效,说明不是语法问题,而是IE11的DOM渲染时机搞的鬼。
你的核心代码:
$('#it option').sort(function(a,b){ return ( $(a).text() > $(b).text() ) ? 1 : -1; }).appendTo( $('#it') ); $('#it option')[0].selected = 'selected';
对应的HTML结构:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="it"> <option val="0">zero</option> <option val="1">one</option> <option val="2">two</option> <option val="3">three</option> <option val="4">four</option> <option val="5">five</option> <option val="6">six</option> </select>
问题根源
IE11在处理appendTo这类DOM重新附加操作时,会有一个微小的内部渲染延迟。当你紧接着执行选中操作时,浏览器还没完成新DOM结构的同步,导致选中状态没有被正确应用到新排序后的选项上。另外,你之前尝试的$('#it option')[0].prop('selected',true)写法有个小错误:$('#it option')[0]拿到的是原生DOM元素,不能直接调用jQuery的prop方法,得用jQuery对象才行。
亲测有效的解决方案
这里有几个经过验证的修复方案,都能在IE11中正常工作,同时不影响现代浏览器的兼容性:
方案1:用jQuery对象正确调用prop方法
把原生DOM元素转为jQuery对象,再设置选中状态,让jQuery帮我们处理兼容性:
$('#it option').sort(function(a,b){ // 用localeCompare替代直接比较,多语言/特殊字符场景更可靠 return $(a).text().localeCompare($(b).text()); }).appendTo('#it'); // 选中第一个选项 $('#it option:first').prop('selected', true);
方案2:直接操作select的selectedIndex属性
跳过选项元素,直接设置select控件的选中索引,这种方式在IE11里稳定性极高:
$('#it option').sort(function(a,b){ return $(a).text().localeCompare($(b).text()); }).appendTo('#it'); // 设置第一个选项为选中项 $('#it')[0].selectedIndex = 0;
方案3:延迟执行选中操作(应急备选)
如果上面的方案都不行,可以把选中操作放到下一个事件循环,给IE11足够时间完成DOM渲染:
$('#it option').sort(function(a,b){ return $(a).text().localeCompare($(b).text()); }).appendTo('#it'); // 用setTimeout把操作推到下一个事件循环 setTimeout(function() { $('#it option')[0].selected = true; }, 0);
额外提示
把排序逻辑里的$(a).text() > $(b).text()换成localeCompare会更可靠,尤其是处理包含特殊字符或者非英语的文本时,兼容性和准确性都更好。
内容的提问来源于stack exchange,提问作者Octopus

