简体   繁体   English

使用JQuery clone()并选择后代元素时,此关闭如何工作

[英]How does this closure work when using JQuery clone() and selecting descendant element

In the below code when the user clicks the "click me" div a new list item is "cloned" and it works the way I would expect. 在下面的代码中,当用户单击“单击我” div时,新列表项被“克隆”,并且按我期望的方式工作。

JSfiddle_1 JSfiddle_1

HTML HTML

  <div class="button">Click me</div>
        <div class="template">
            <li>oink</li>
        </div>

    <ul>
    </ul>

JavaScript JavaScript的

$(".button").on("click",function(){

    var result = $('.template li').clone(); //______Descendant selector
    $("ul").append(result);
});

However, in the version of the code below I modified the code to not have a descendant selector. 但是,在下面的代码版本中,我修改了代码,使其没有后代选择器。 In this version when you click the "click me" div the number of elements is compounded on each click which tells me a closure is happening, but what I don't understand is why this doesn't happen when adding a descendant selector. 在此版本中,当您单击“单击我” div时,每次单击会增加元素数量,这告诉我正在发生关闭,但是我不明白的是为什么在添加后代选择器时却没有发生这种情况。 Any clarification is appreciated. 任何澄清表示赞赏。 Thank you 谢谢

JSfiddle_2 JSfiddle_2

HTML HTML

<div class="button">Click me</div>
    <div class="template">
        <li>oink</li>
    </div>

<ul>
</ul>

JavaScript JavaScript的

$(".button").on("click",function(){

    var result = $('li').clone(); //______No descendant selector
    $("ul").append(result);
});

$('.template li') selects descendant <li>s of just the .template <div> which is just one in your case. $('.template li')选择.template <div>后代<li>s ,在您的情况下,该$('.template li')只是一个。 This is what Descendant selector is used for - To get specific elements, instead of all. 这就是Descendant选择器的用途-获取特定元素而不是全部元素。

$(".button").on("click",function(){

    var result = $('.template li').clone(); //______Descendant selector
    $("ul").append(result);
});

While just $('li') selects <li>s from the whole DOM (initial + newly appended). $('li')从整个DOM中选择<li>s (初始+新添加)。 The number of li elements resulting from $('li') will increase with the append . $('li')产生的li元素的数量将随着append增加而增加。

$(".button").on("click",function(){
    var result = $('li:first').clone(); //______No descendant selector
    $("ul").append(result);
});

HTML at 2nd click, you can see there are two <li> at this point of time. 第二次单击HTML,您可以看到此时有两个<li> So $('li') appends two elements and so on. 因此$('li')追加了两个元素,依此类推。

<div class="button">Click me</div>
<div class="template">
    <li>oink</li>
</div>

<ul>
    <li>oink</li>
</ul>

Why this doesn't work? 为什么这不起作用?

Lets take it here: 让我们在这里:

<div class="button">Click me</div>
<div class="template">
    <li>oink</li>
</div>

<ul>
</ul>

As you can see in your markup there is one li in the markup but that is not a valid way to put any list item outside of ul/ol . 正如您在标记中看到的那样,标记中只有一个li ,但这不是将任何列表项置于ul/ol之外的有效方法。 Only ul/ol s can have the list items. 只有ul/ol可以具有列表项。

This is just a simple info but in your code the issue seems to be here: 这只是一个简单的信息,但是在您的代码中,问题似乎在这里:

$(".button").on("click",function(){
    var result = $('li').clone(); //______No descendant selector
    $("ul").append(result);
});

This line: 这行:

var result = $('li').clone(); 

returns you a collection of list items available in the page. 返回页面中可用列表项的集合。 So if you have one list item at first click then it returned only one li then append gets executed. 因此,如果您首先单击一个列表项,那么它仅返回一个li然后执行append。 so there is now two li s, now if you click then you would see two li s are getting appended. 所以现在有两个li ,如果单击,您会看到两个li被附加。

Solution: 解:

so the simplest solution is to use :first : 所以最简单的解决方案是使用:first

$(".button").on("click",function(){
    var result = $('li:first').clone(); //______No descendant selector
    $("ul").append(result);
});

now this line: 现在这行:

$('li:first').clone();

always returns you the first element found in the structure. 总是返回您在结构中找到的第一个元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM