在下面的代码中,当用户单击"单击我"div时,一个新的列表项被"克隆",它的工作方式符合我预期。
JSfiddle_1
.HTML
<div class="button">Click me</div>
<div class="template">
<li>oink</li>
</div>
<ul>
</ul>
JavaScript
$(".button").on("click",function(){
var result = $('.template li').clone(); //______Descendant selector
$("ul").append(result);
});
但是,在下面的代码版本中,我修改了代码以没有后代选择器。在这个版本中,当您单击"单击我"div 时,每次单击时元素的数量都会复合,这告诉我正在发生闭包,但我不明白的是为什么在添加后代选择器时不会发生这种情况。任何澄清都值得赞赏。谢谢
JSfiddle_2
.HTML
<div class="button">Click me</div>
<div class="template">
<li>oink</li>
</div>
<ul>
</ul>
JavaScript
$(".button").on("click",function(){
var result = $('li').clone(); //______No descendant selector
$("ul").append(result);
});
$('.template li')
仅选择.template
<div>
的后代<li>s
,在您的情况下只是一个。这就是后代选择器的用途 - 获取特定元素,而不是所有元素。
$(".button").on("click",function(){
var result = $('.template li').clone(); //______Descendant selector
$("ul").append(result);
});
虽然只有$('li')
从整个 DOM 中选择<li>s
(初始 + 新附加)。由$('li')
产生的li
元素的数量将随着append
而增加。
$(".button").on("click",function(){
var result = $('li:first').clone(); //______No descendant selector
$("ul").append(result);
});
在第二次单击时,您可以看到此时有两个<li>
。所以$('li')
附加了两个元素,依此类推。
<div class="button">Click me</div>
<div class="template">
<li>oink</li>
</div>
<ul>
<li>oink</li>
</ul>
为什么这不起作用?
让我们把它放在这里:
<div class="button">Click me</div>
<div class="template">
<li>oink</li>
</div>
<ul>
</ul>
<小时 />正如您在标记中看到的那样,标记中有一个li
,但这不是将任何列表项放在ul/ol
之外的有效方法。只有ul/ol
可以具有列表项。
这只是一个简单的信息,但在您的代码中,问题似乎在这里:
$(".button").on("click",function(){
var result = $('li').clone(); //______No descendant selector
$("ul").append(result);
});
这一行:
var result = $('li').clone();
返回页面中可用的列表项的集合。因此,如果您在第一次单击时有一个列表项,那么它只返回一个li
然后执行追加。所以现在有两个li
,现在如果你点击,你会看到两个li
被附加。
溶液:
所以最简单的解决方案是使用 :first
:
$(".button").on("click",function(){
var result = $('li:first').clone(); //______No descendant selector
$("ul").append(result);
});
现在这一行:
$('li:first').clone();
始终返回在结构中找到的第一个元素。