jQuery如何将元素添加到空选择集中?

40

为什么这个不起作用?

var spans = $();
var elem = document.getElementById('someId');
spans.add(elem);

如何以空集合开始并向其中添加元素? 我希望遍历id的集合,查找页面上的元素,并将其添加到匹配集中。


根据jQuery版本的不同,创建一个空的jQuery对象可能需要使用$([])而不是$()。请参见https://dev59.com/kHI-5IYBdhLWcg3wI0p9。 - allicarn
9个回答

55

引用自jQuery官网:

.add()方法接受一个表示一组DOM元素的jQuery对象,并在该组元素和传递给方法的元素之间构建一个新的jQuery对象。

因此,当你使用.add()时,它不会保存添加的元素,你需要显式地将元素分配给新创建的对象,即:

var $elements = $('.elements');
$elements = $elements.add($('#anotherelement'));

1
所有答案基本上都是正确的。我只需要重新分配原始变量。这是解决方案的关键。谢谢大家。 - Hcabnettek
1
只是想知道人们从什么时候开始在JavaScript中使用$符号?这是PHP中最烦人的部分,为什么要在其他语言中使用它呢? - Srneczek
@Srneczek 他们在前面加上一个“sigil”来明确它是一个“jQuery选择”对象,而不是一个常规的js数组/对象。这里有一个SO问题,解释得更详细:https://dev59.com/k3RA5IYBdhLWcg3wvQhh - Eric Seastrand
@Eric 哦,我明白了,这确实是最佳实践,但在变量前加任何符号仍然是纯粹的打字恶魔。 - Srneczek

15
< p > .add() 方法返回一个新的 jQuery 对象,因此您需要覆盖旧对象:

spans = spans.add( elem );

...或者,由于您正在添加DOM元素,您可以使用.push()修改现有的jQuery对象。

spans.push( elem );

编辑:.pushStack()更改为.push(),尽管我不知道.push()是否得到了官方支持。


你可以使用.pushStack()来添加一个集合。

spans = spans.pushStack( [elem] );
或者
spans = spans.pushStack( document.getElementsByTagName('div') );

2
jQuery 1.6.2代码中的注释说push()仅供内部使用,而且不在jQuery文档中。使用.add()并将新的jQuery对象分配给变量span似乎更安全。 - jfriend00
@jfriend00:是的,有几个这样的。如果它们得到支持就好了。 - user113716
2
我认为其中一个问题是jQuery喜欢保持DOM元素的唯一性(无重复项)和(我认为)按DOM顺序排列,而.push()不会这样做,因为它直接将某些内容添加到数组中。jQuery代码经常执行.push(),然后跟着一个.unique(),以便将事物放回它们想要保持的方式。 - jfriend00

7

我猜我不明白你的问题。如果你有一个元素,并且想将它添加到集合中,那么你只需要使用.add()方法,就像你已经展示的那样。有些人会感到困惑的是这会返回一个新的jQuery对象,所以你需要这样做:

var spans = $();
var elem = document.getElementById('someId');
spans = spans.add(elem);

当然,这样的东西会更短:

var spans = $();
spans = spans.add('#someId');

当然,您不必从空对象开始。您只需从以下内容开始:

var spans = $('#someId');

1
“有些人困惑的是,这会返回一个新的 jQuery 对象。” - 我认为这是最好的答案。 - John Boe

5
如果您想从jQuery对象中选择要推送(push)添加(add)的项目,也可以这样做:
var $els = $(),
    $someEls = $(".some-els");

$els.push.apply($els, $someEls);

另一种实现方式。


1
实际上,这个方法似乎是唯一解决问题的方法:将不仅是选定元素,而且是新创建的元素添加到空的、分离的集合中。当我创建长列表然后将结果分离的集合附加到最终的dom元素时,我喜欢这种方法。我想知道为什么只有$els.push($someEls)失败了。 - rupps
谢谢 - 这是因为您正在将一个数组推到另一个数组上。apply方法会将扩展的jQuery数组分离出来,并将每个单独的元素推送到它上面。就像 var arr = []; arr.push.apply([1,2,3]); 一样。 - marksyzm
1
“add” 可能会重新排序底层数组,这是我不能接受的。 - Teepeemm

2
你实际想要做的是充分利用jQuery的功能。你可以使用选择器立即获取和创建集合。你上面的三行变成了一行:
var spans = $('#someId');

要将更多的id添加到集合中,您可以用逗号分隔它们:

var spans = $('#someId1, #someid2, #someid3');

公正地说,jQuery的“预期目的”可能比你认为的要广泛一些... - jmar777

1
虽然这并没有直接回答“如何向现有的jQuery选择添加内容”的问题,但我有一个针对这个特定用例的解决方法。
您可以将DOM元素数组传递给jQuery,它将创建一个jQuery选择器。
var spansArray = [];
var elem = document.getElementById('someId');
spansArray.push(elem);
var spans = $(spansArray);

我想不出为什么你需要逐个添加每个元素到jQuery选择器中,而不是一次性添加所有元素,因此这应该是你使用的情况下的“即插即用替代品”。理论上,这也必须证明更有效率,因为jQuery的.add()最终只是在幕后调用一些数组上的.push()

1

可能有更好的方法来完成你尝试做的事情,但如果你只想创建一个空的jQuery对象,请使用这个:

var $foo = $([]);


编辑:我应该澄清一下 - 你的代码实际上应该是可以工作的,除非你使用的是旧版本的jQuery,在这种情况下$()会创建一个包含document对象的集合。然而,在较新的版本中,这没有任何问题。我上面粘贴的代码片段只是在旧版本和新版本的jQuery中都能正常工作的东西。
编辑2:针对问题中的这部分内容:"我想循环遍历一组ID,并找到页面上的元素并将其添加到匹配集中",以下代码可能会有用:

var ids = ['foo', 'bar', 'baz'],
    selector = $.map(ids, function(i, id) {
        return '#' + id;
    }).join(','),
    $collection = $(selector);

0

尝试

var spans = $("<span />");
var elem = $("#someId").html();
spans.append(elem).appendTo('#someAnotherId');

替代


0
你的代码无法正常工作是因为add不会改变集合,它返回一个包含新元素的新jQuery对象。如果你想的话,你可以使用spans = spans.add(elem);,但这样做是不必要的:jQuery的美妙之处在于它使得这种命令式编程变得不必要。看看helloandre的答案,实现你的目标会更容易。
就像下面这样,如果这样说有意义的话:
var x = [1, 2, 3];
x.concat(4);
console.log(x); // [1, 2, 3] -- concat does not mutate the original array

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接