Как обновить ссылку на элемент HTML после того, как я использовал appendChild с нативным JavaScript - PullRequest
2 голосов
/ 07 марта 2019

Я использую собственный javascript для добавления элемента в DOM, который исчезает через X секунд.

Чтобы добавить элемент, я создаю фрагмент документа с функцией createHTML Затем я добавляю этот элемент кмой контейнерный элемент.

var elementHTML = '<div>Test element appended</div>';
    elementHTML = createHTML(elementHTML);      
document.getElementById('append-container').appendChild(elementHTML);

Затем я установил тайм-аут, который удаляет элемент из DOM через x секунд

setTimeout(function() {
    elementHTML.parentNode.removeChild(elementHTML);
}, 2000, elementHTML); 

Теперь это не будет работать, потому что при использовании appendChildэлементы перемещаются и ссылка на элемент теряется.Я ищу способ обновить ссылку для elementHTML на элемент, который я только что добавил в DOM.

В основном я ищу функциональность ссылок jQuery без использования jQuery.

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

Мне интересно, есть ликакой-то обратный вызов, когда вы добавляете что-то в DOM для нацеливания на то, что вы только что добавили, или если моя логика заключается в том, что это просто неправильно.

FIDDLE

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Проблема в том, что DocumentFragment переместит содержимое фрагмента в новое место в DOM, но сам фрагмент останется фрагментом, не связанным напрямую ни с чем:

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

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

В конце концов, в противном случае, если строка HTML -

<div>Test element appended</div><div>Test element 2 appended</div>

, на что может ссылаться добавленная documentFragment?Это не может быть просто один или другой <div>, а также не может быть родительским элементом (который уже был в DOM и не был создан с фрагментом).

Итак, однажды documentFragment добавлен, он не может быть удален за один раз.

Если фрагмент гарантированно содержит только один элемент, как в вашем примере, выберите этот элемент и добавьте it (а затем вы можете правильно ссылаться на его parentNode).

// though using a documentFragment in the first place is a bit odd
// if you're not going to append it

var createHTML = function(htmlStr) {
  var frag = document.createDocumentFragment(),
    temp = document.createElement('div');
  temp.innerHTML = htmlStr;
  while (temp.firstChild) {
    frag.appendChild(temp.firstChild);
  }
  return frag;
}

var appendItems = function() {
  const elementHTML = '<div>Test element appended</div>';
  const fragment = createHTML(elementHTML);
  const fragmentElm = fragment.children[0];
  document.getElementById('append-container').appendChild(fragmentElm);
  setTimeout(function() {
    fragmentElm.parentNode.removeChild(fragmentElm);
  }, 2000, elementHTML);
}

document.getElementById('test-append').addEventListener('click', appendItems);
<div id="append-container">

</div>

<button id="test-append">
  Test
</button>

Другой вариант - перебрать все добавленные узлы и .remove() их:

var createHTML = function(htmlStr) {
  var frag = document.createDocumentFragment(),
    temp = document.createElement('div');
  temp.innerHTML = htmlStr;
  while (temp.firstChild) {
    frag.appendChild(temp.firstChild);
  }
  return frag;
}

var appendItems = function() {
  const elementHTML = '<div>Test element appended</div><div>Test element 2 appended</div>';
  const fragment = createHTML(elementHTML);
  const fragmentElms = [...fragment.children];
  const container = document.getElementById('append-container');
  fragmentElms.forEach((elm) => {
    container.appendChild(elm);
  });
  setTimeout(function() {
    fragmentElms.forEach((elm) => {
      elm.remove();
    });
  }, 2000, elementHTML);
}

document.getElementById('test-append').addEventListener('click', appendItems);
<div id="append-container">

</div>

<button id="test-append">
  Test
</button>
1 голос
/ 07 марта 2019

Присоединение узлов в цикле while не нужно: innerHTML уже делает это за вас.

var createHTML = function(htmlStr) {
    var temp = document.createElement('div');
    temp.innerHTML = htmlStr;
    return temp;
}

Таким образом - без фрагмента DOM - удалениеЭлемент после тайм-аута работает как ожидалось.

...