Двойное добавление элемента DOM (jQuery)

Может ли кто-нибудь объяснить, почему следующий фрагмент не добавляет <foo> к #a и #b?

HTML:

<div id="a"></div>
<div id="b"></div>

JS:

$(function(){
    var $foo = $("<foo>HI</foo>");
    $("#a").append($foo);
    $("#b").append($foo);
});

jsfiddle

Редактировать: спасибо за полезные советы, тот факт, что .append() перемещает элемент, объясняет такое поведение. Поскольку элемент в моем приложении на самом деле является .el Backbone View, я предпочитаю не клонировать его.


person parsa    schedule 16.07.2013    source источник
comment
Если элемент уже присутствует в DOM, append() просто перемещает его. Вот почему при втором добавлении элемент просто перемещается из #a в #b.   -  person adeneo    schedule 16.07.2013


Ответы (5)


Потому что использование append фактически перемещает элемент. Таким образом, ваш код перемещал $foo в документ в #a, а затем перемещал его из #a в #b. Вы можете клонировать его вместо этого для желаемого эффекта - таким образом, он добавляет клон, а не исходный элемент:

$(function(){
    var $foo = $("<foo>HI</foo>");
    $("#a").append($foo.clone());
    $("#b").append($foo.clone());
});

Вы также можете добавить html из $foo, что просто возьмет копию dom внутри него, а не сам элемент:

$(function(){
    var $foo = $("<foo>HI</foo>");
    $("#a").append($foo[0].outerHTML);
    $("#b").append($foo[0].outerHTML);
});

В приведенных выше примерах предполагается, что у вас есть более сложный сценарий, в котором $foo — это не просто объект jQuery, созданный из строки... более вероятно, что он создан из элемента в вашей модели DOM.

Если на самом деле он просто создан таким образом и для этой цели... для начала нет причин создавать этот объект jQuery, вы можете просто добавить саму строку ("<foo>HI</foo>") напрямую, например:

var foo = "<foo>HI</foo>";
$("#a").append(foo);
//...
person Dallas    schedule 16.07.2013
comment
@Radmation, у вас, вероятно, другая проблема, проверьте свою консоль, и если это не поможет ... задайте новый вопрос со всей необходимой информацией. - person Dallas; 12.05.2016

Попробуйте clone. Это, как следует из названия, скопирует элемент $foo, а не переместит его, как это сделает append.

$(function(){
    var $foo = $("<foo>HI</foo>");
    $("#a").append($foo.clone());
    $("#b").append($foo.clone());
});

Но почему бы просто не использовать это?

$("#a,#b").append($foo);

Это тоже будет работать :)

Вот демонстрация для обеих этих ситуаций: http://jsfiddle.net/hungerpain/sCvs7/3/

person krishwader    schedule 16.07.2013

Вам нужно create a new instance каждый раз, когда вы хотите добавить в DOM.

В противном случае он относится к тому же экземпляру, который уже был добавлен.

Удалите символ $, предшествующий новому элементу div, который будет добавлен, поскольку он оценивается как объект jQuery и имеет указанные выше ограничения. или clone элемент.

$(function(){
    var foo = "<foo>HI</foo>";
    $("#a").append(foo);
    $("#b").append(foo);
});

Проверить Fiddle

person Sushanth --    schedule 16.07.2013
comment
Чтобы сделать вашу точку зрения более ясной, я бы предложил также удалить префикс $ из переменной foo, так как теперь она содержит строку вместо объекта jQuery. - person Frédéric Hamidi; 16.07.2013

Вы можете использовать метод .clone() для создания нового экземпляра для добавления в DOM, поскольку ваш текущий код просто дважды ссылается на один и тот же экземпляр.

$(function(){
    var $foo = $("<foo>HI</foo>");
    var $foo2 = foo.clone();
    $("#a").append($foo);
    $("#b").append($foo2);
});
person Jnatalzia    schedule 16.07.2013

Я попробовал трюк, и он сработал. Я просто вложил функцию нажатия одной кнопки в другую. я имею в виду, что каждый раз меняю родителя, чтобы избежать этой проблемы. главное, что когда я пишу функцию щелчка для кнопки 1, логика кнопки 2 записывается под ней, а логика нажатия кнопки 3 записывается внутри метода нажатия кнопки 2, как иерархия. Просто посмотрите код. ты получишь это.

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />

    <!-- Bootstrap CSS -->
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
      integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
      crossorigin="anonymous"
    />

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>DOM Element Inserting!</h1>
    <div id="parent">
      <div id="result">
        <button id="btn1" type="submit" class="btn btn-primary">
          Start Cooking
        </button>
      </div>
    </div>
    <div id="parent2"></div>
    <div id="parent3"></div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script
      src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
      integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
      integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
      integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV"
      crossorigin="anonymous"
    ></script>
    <script>
      $(document).ready(function () {
        $("#btn1").click(function () {
          $("#lt").remove();
          $("#parent2").html(`

                <button id="btn2" type="button" class="btn btn-success">
        Being Prepared
      </button>
                `);
          $("#btn1").remove();
          $("#btn2").click(function () {
            $("#parent3").html(`

                <button id="btn3" type="button" class="btn btn-info">
        Order Ready
      </button>
                `);
            $("#parent2").remove();
            $("#btn3").click(function () {
              alert("Order Completed!!");
            });
          });
        });
      });
    </script>
  </body>
</html>

person TechyPREETish    schedule 01.10.2020
comment
Я не понимаю, как это связано с вопросом, которому, кстати, 7 лет. - person tobiv; 01.10.2020
comment
Это просто альтернатива... чтобы страница вел себя так же... если у вас есть другой способ сделать это... поделитесь ею... - person TechyPREETish; 02.10.2020