Как работает это закрытие при использовании JQuery clone() и выборе элемента-потомка

В приведенном ниже коде, когда пользователь нажимает div "click me", новый элемент списка "клонируется" и работает так, как я ожидал.

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 "click me", число элементов составляется при каждом щелчке, что говорит о том, что происходит закрытие, но я не понимаю, почему это не происходит при добавлении селектора потомков. Любые разъяснения приветствуются. Спасибо

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);
});

2 ответа

Решение

$('.template li') выбирает потомка <li>s только из .template<div> который только один в вашем случае. Для этого используется селектор Descendant - для получения определенных элементов, а не всех.

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

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

Пока просто $('li') выбирает <li>s из всего DOM (начальный + недавно добавленный). Номер li элементы, вытекающие из $('li') будет увеличиваться с append,

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

HTML при втором клике, вы можете увидеть, что есть два<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/ols может иметь элементы списка.

Это просто простая информация, но в вашем коде проблема, кажется, здесь:

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

Эта строка:

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

возвращает вам коллекцию элементов списка, доступных на странице. Таким образом, если у вас есть один элемент списка при первом нажатии, он вернул только один li тогда приложение будет выполнено. так что теперь два lis, теперь, если вы нажмете, то вы увидите два liS добавляются.

Решение:

поэтому самое простое решение заключается в использовании :first:

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

теперь эта строка:

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

всегда возвращает вам первый элемент, найденный в структуре.

Другие вопросы по тегам