【发布时间】:2013-01-01 22:08:45
【问题描述】:
我正在编写自己的 jQuery 插件,其中我引用了一些现有节点,并创建了一些在 DOM 树中不存在的新 jQ 节点(它们没有附加)。我正在使用.add() 方法将每个元素添加到新集合中。
发生的情况是,这个集合的顺序看起来很奇怪(我在那里找不到任何逻辑模式)。文档中的以下注释可能是原因:
从 jQuery 1.4 开始,来自 .add() 的结果将始终按文档顺序返回(而不是简单的串联)。
考虑以下示例。
HTML
<body>
<a id="existing1"></a><a id="existing2"></a>
</body>
JS
<script type="text/javascript">
function addToColl(selector) {
coll = coll.add(selector);
var n = $(selector).get(0).id.match(/\d+/)[0];
for (var i = 0; i < 4; i++) {
var a = $('<a>',{id:'virtual'+n+'_'+i});
coll = coll.add(a);
}
}
$(document).ready(function() {
coll = $();
addToColl('#existing1');
// uncomment the following to see what's happening
//addToColl('#existing2');
$.each(coll,function(idx,elm) {
console.log(elm.id);
});
});
</script>
输出:
现有1
虚拟1_0
虚拟1_1
虚拟1_2
虚拟1_3
当你取消注释被注释的函数调用它输出
现有1
虚拟1_3
虚拟1_2
虚拟1_1
虚拟1_0
现有2
虚拟2_0
虚拟2_1
虚拟2_2
虚拟2_3
应该怎么做才能避免这种混乱?
------ [编辑] ------
由于add() 函数的意外行为,我最终使用原生Javascript 数组来收集元素(即使用push() 方法)。稍后,当我收集完元素后,我会将其转换为 jQuery 集合。
【问题讨论】:
-
您是否尝试定义 coll = $([]);而不是 coll = $();
-
文档中的注释仅适用于集合中的所有元素都在 DOM 中的情况。如果不是,则由于合并集合的方式,该顺序是不可预测的。
-
@YoniBaciu 不幸的是,它没有改变任何东西。
-
@Barmar 我认为,它在内部首先搜索 DOM 树中的元素,然后通过
for..in循环或其他方式重新创建集合,这会改变元素的顺序。但有趣的是,这在任何地方都没有提及。 -
我认为他们只是没有考虑一个集合可能同时包含连接和断开连接的元素。代码实际上并不是很小心。