jQuery:使用.after()或.before()将元素添加到仅选择中的最后一项

时间:2014-02-26 15:54:46

标签: javascript jquery html

我一直在使用jQuery,但这是一个新的。一个简化的例子:

HTML

<div class='custom'></div>
<div class='custom'></div>
<div class='custom'></div>

jQuery的:

var $customElems = $('.custom'),
    $spanOuter   = $('<span class="outer"/>'),
    $spanInner   = $('<span class="inner"/>');

$customElems.each( function() {
    $(this).wrap($spanOuter).after($spanInner);
});

的jsfiddle: http://jsfiddle.net/a3ZK8/

我原本期望将“内部”跨度添加到选择中的所有三个元素,但它总是只插入到最后一个(无论多少)。我用.before()尝试了它,有和没有链接,相同的结果。我错过了什么?

3 个答案:

答案 0 :(得分:3)

问题是您正在使用引用来构建jQuery对象。

因此,您将在每次迭代中不断移动对象引用

如果您没有附加事件或者不需要span成为jQuery对象,那么只需将参数作为HTML字符串文字而不是对象引用

传递

首先克隆一个不需要成为jQuery对象的jQuery对象只是冗余处理和不必要的开销。

将jQuery对象更改为类似于此字符串的字符串:

spanInnerString  = '<span class="inner"/>';

和你的方法是这样的:

$(this).wrap($spanOuter).after(spanInner);

结果是:

<span class="outer"><div class="custom"></div><span class="inner"></span></span>
<span class="outer"><div class="custom"></div><span class="inner"></span></span>
<span class="outer"><div class="custom"></div><span class="inner"></span></span>

DEMO - 将参数作为HTML字符串传递


当然,外跨度也是如此。除非必须,否则不要创建jQuery对象。

如果你必须使用jQuery对象,因为你想要将事件附加到span或类似物,那么克隆就是要走的路,但要确保你使用clone(true, true)然后克隆附件事件

答案 1 :(得分:2)

您需要克隆元素。否则,after()将重新定位相同的元素3次,这将导致它仅附加到最后一个循环元素。

$customElems.each(function () {
    $(this).wrap($spanOuter).after($spanInner.clone());
});

演示:Fiddle

你可能会问,“为什么wrap()会工作?”那是因为'wrap()'在内部clones the element

答案 2 :(得分:2)

你在同一个地方移动相同的距离。如果您同时对所有三个div执行操作,则jquery将克隆该跨度。

http://jsfiddle.net/a3ZK8/1/

var $customElems = $('.custom'),
    $spanOuter = $('<span class="outer"/>'),
    $spanInner = $('<span class="inner"/>');

$customElems.wrap($spanOuter).after($spanInner);

来自.after:

的文档
  

重要提示:如果有多个目标元素,则克隆   将为每个目标创建插入元素的副本,除外   为了最后一个。

表示最后一个元素将始终获取原始元素,而所有其他选定元素将获得克隆。这就是为什么当你一次对一个元素进行操作时,它只是移动了相同的范围。