元素排序例程在Firefox中工作,但在Chrome中崩溃
Element sort routine works in Firefox, but crashes in Chrome
我编写了以下例程来对select
中的option
元素进行排序:
function SortSelect(select)
{
var tmpAry = new Array();
for (var i in select.options)
tmpAry[i] = select.options[i];
tmpAry.sort(function(opta, optb)
{
if (opta.id > optb.id) return 1;
if (opta.id < optb.id) return -1;
return 0;
});
while (select.options.length > 0)
select.options[0] = null;
for (var i in tmpAry)
select.appendChild(tmpAry[i]);
}
作为Greasemonkey脚本的一部分,它在Firefox中工作得很好。然而,在Chrome中,无论有没有TamperMonkey,我得到这个:
Uncaught Error: NOT_FOUND_ERR: DOM Exception 8
SortSelect:125
与Javascript调试器的典型情况一样,错误行号完全错误,因此很难准确确定为什么会出错以及在哪里出错。我是开放的建议,为什么代码是调试或方法有效地调试它(我是新的Chrome)。谢谢。
应该使用索引来遍历选项集合,而不是使用for..in循环。如下:
for (var i in select.options) {
tmpAry[i] = select.options[i];
应:var options = select.options;
for (var i=0, iLen=options.length; i<iLen; i++) {
tmpAry[i] = options[i];
}
您可能会从选项集合中获得不是选项元素的属性,例如长度。
你也不应该给一个选项赋值"null"。如果要删除所有选项,只需将选项的长度设置为零:
var options.length = 0;
最后,您应该使用索引遍历tmpAray,因为for..in 不会在每个浏览器中以相同的顺序返回选项,并且可能返回非数字可枚举属性(如果有),使用索引。此外,您可以将该选项分配回select的选项集合,不需要使用appendChild:
select.options.length = 0;
for (var i=0, iLen=tmpAry.length; i<iLen; i++) {
select.options[i] = tmpAry[i];
}
如果你没有删除任何选项,你应该能够按照新的顺序分配它们,但有些浏览器不能处理这个问题,所以最好先删除它们。
编辑
注意,select元素的options属性是只读的,而options集合的属性则不是。你可以直接给它们赋值(应该是对option元素的引用)
你想用这段代码做什么?
while (select.options.length > 0)
select.options[0] = null;
如果答案是你试图清除所有的选择选项,这似乎很危险。我可以看出这很容易成为一个无限循环。
在我看来,这样会安全得多:
for (var i = select.options.length - 1; i > 0; i--) {
select.remove(i);
}
然后,有一个select.options.add()
方法将它们添加回去。
仅供参考,在数组或伪数组上使用这种结构也被认为是有风险的做法:
for (var i in select.options)
for (var i in tmpAry)
,因为除了数组元素之外,它还可以拾取添加到对象中的属性。
输入更多,但使用更安全:
for (var i = 0, len = tmpAry.length; i < len; i++) {
// code here
}
这些行可能导致无限循环或访问冲突:
while (select.options.length > 0)
select.options[0] = null;
同样,您不需要删除节点并重新插入它们;appendChild()
在所有浏览器中都可以很好地移动节点。
因此,这段代码可以工作,并且应该比删除和重新创建节点(这也可以丢弃任何事件侦听器)更有效。:
查看jsFiddle的实际操作
function SortSelect (select)
{
var tmpAry = [];
for (var J = select.options.length - 1; J >= 0; --J)
tmpAry.push (select.options[J] );
tmpAry.sort ( function (opta, optb) {
if (opta.id > optb.id) return 1;
if (opta.id < optb.id) return -1;
return 0;
} );
while (tmpAry.length) {
select.appendChild ( document.getElementById (tmpAry[0].id) );
tmpAry.shift ();
}
}
- jQuery自动完成在Firefox中运行良好,但在Chrome中则不然
- Javascript下载在firefox中停止,但在Chrome中有效
- Javascript'元素'在ie中未定义,但在chrome和firefox中运行良好
- 这个jQuery代码在Mozilla上运行良好,但在Chrome,Opera,Safari上则不然
- 火狐中的多个问题,但在 chrome 中工作正常,没有一个问题
- 在Firefox中工作正常,但在Chrome中不能
- Javascript正则表达式在IE中失败,但在Chrome和Edge中工作
- Javascript键码在Firefox中不起作用,但在chrome中运行良好
- 输入类型的图像在Internet Explorer中不起作用,但在Chrome和Firefox中起作用
- Jquery.hide()和.show()在firefox上运行速度较慢,但在chrome上运行良好
- 在getJSON之后构建HTML在Safari中有效,但在Chrome或Firefox中无效
- JS函数如何/为什么不能'不能在代码中执行,但在chrome控制台中运行良好
- html数据属性在firefox中使用javascript时没有按预期显示,但在chrome中显示正确
- ng-click在IE中不起作用,但在CHROME中工作正常
- event.prventdefault()在mozilla中不起作用,但在chrome中运行良好
- 代码在firefox中运行良好,但在chrome中不起作用.为什么?
- 拖放文件时,dataTransfer.items属性在Firefox和IE中未定义,但在Chrome中未定义
- jQuery scrollTop没有'不能在FF或IE中制作动画,但在chrome中效果良好
- innerHTML=Date()在fiddle中工作,但在Chrome或IE中不工作
- Fullpage.js不能在Mozilla上运行,但在Chrome上运行良好