HTML-элемент добавляется в цикл Javascript for, а затем удаляется при увеличении счетчика

Я работаю над решением для упражнения «зацикливание треугольника» в конце Eloquent JavaScript ch2. Книга просит вывести вывод на консоль, но вместо этого я хочу распечатать вывод на веб-страницу в div с id="triangle".

Этот код печатает правильное количество хэшей. Проблема в том, что тег
, созданный в цикле for, загадочным образом удаляется, когда цикл увеличивает конечное выражение. То есть: если я пошагово выполняю код, hashPrint.appendChild(carriage) выполняется нормально в точке останова, но как только отладчик переходит к i++, дочерний элемент
удаляется с веб-страницы.

var hash = "";
var hashPrint = document.getElementById("triangle");
var carriage = document.createElement("br");

for (var i = 0; i < 7; i++) {
    hash += "#";
    var content = document.createTextNode(hash);
    hashPrint.appendChild(content); 
    hashPrint.appendChild(carriage);
}

Если я поместил объявление каретки var в цикл for, он отлично работает. Я знаю, что лучшая практика JS поощряет избегать глобальной области видимости, в последнее время я много программировал на Java, и мне показалось, что наличие createElement("br") в глобальном масштабе может быть удобным, если я хочу использовать его в другом цикле на странице.

Несмотря на то, что у меня уже есть решение этой проблемы, я хотел бы знать, почему последнее выражение в цикле for вызовет удаление дочернего узла. В общем, почему это не работает? Я искал объяснение вверху и внизу, но безуспешно.


person alodrummer    schedule 07.05.2018    source источник
comment
appendChild удаляет элемент из DOM, прежде чем добавить его в новую позицию.   -  person Jonas Wilms    schedule 07.05.2018


Ответы (2)


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

for (var i = 0; i < 7; i++) {
  hash += "#";
  var content = document.createTextNode(hash);
  hashPrint.appendChild(content);
  var carriage = document.createElement("br");
  hashPrint.appendChild(carriage);
}
person epascarello    schedule 07.05.2018
comment
Я также не уверен, что вы можете добавить несколько текстовых узлов к одному и тому же элементу. - person Jonathan; 07.05.2018
comment
Да, у меня работал тот же код, и мне было интересно, почему код в моем примере не работает. Я думаю, что понял. При объявлении узла вне цикла он создается только один раз, а затем перемещается в DOM с помощью appendChild() после каждой итерации цикла. Я все еще думаю, что странно, что узел удаляется при увеличении, а затем не заменяется до тех пор, пока метод не будет вызван снова. - person alodrummer; 10.05.2018

Попробуйте клонировать узел, иначе appendChild() съест его:

var hash = "";
var hashPrint = document.getElementById("triangle");
var carriage = document.createElement("br");

for (var i = 0; i < 7; i++) {
    hash += "#";
    var content = document.createTextNode(hash);
    hashPrint.appendChild(content); 
    hashPrint.appendChild(carriage.cloneNode(true));
}

См.: https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild

или Почему cloneNode необходимо использовать, когда добавление documentFragment?

person Jonathan Rys    schedule 07.05.2018