Javascript удаление дочернего элемента

Как я могу удалить все дочерние элементы DOM node в JavaScript?

Скажем, у меня есть следующий (уродливый) HTML:

И я хватаю node Я хочу так:

Как удалить дочерние элементы foo , чтобы оставить только

Могу я просто сделать:

или я должен использовать некоторую комбинацию removeElement ?

Я бы хотел, чтобы ответ был прямо DOM; хотя дополнительные пункты, если вы также предоставляете ответ в jQuery вместе с ответом DOM.

Вариант 1 (намного медленнее, см. комментарии ниже):

Вариант 2 (намного быстрее):

В настоящее время принят неправильный ответ о том, что innerHTML медленнее (по крайней мере, в IE и Chrome), как правильно заметил m93a.

Chrome и FF значительно быстрее используют этот метод (который уничтожит вложенные данные jquery):

в считанные секунды для FF и Chrome и быстрее всего в IE:

InnerHTML не разрушит ваши обработчики событий и не нарушит ссылки на jquery, также рекомендуется в качестве решения здесь: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML.

Самый быстрый метод манипулирования DOM (все еще медленнее, чем предыдущие два) — это удаление Range, но диапазоны не поддерживаются до IE9.

Другие упомянутые методы кажутся сопоставимыми, но намного медленнее, чем innerHTML, за исключением выброса jquery (1.1.1 и 3.1.1), который значительно медленнее, чем что-либо другое:

Jsperf "per-test-loop" часто понимается как "per-iteration", и только в первой итерации есть узлы для удаления, поэтому результаты не имеют смысла, на момент публикации в этом потоке были неправильно настроены тесты.

как я могу удалить все дочерние элементы узла DOM в JavaScript?

скажем, у меня есть следующий (уродливый) HTML:

и я хватаю узел, который я хочу так:

как я мог удалить детей foo Так что просто

могу я просто сделать:

или я должен использовать некоторые комбинации removeElement ?

Я хотел бы, чтобы ответ был прямым до дома; хотя дополнительные очки, если вы также предоставляете ответ в jQuery вместе с ответом только DOM.

25 ответов

Вариант 1 (намного медленнее, см. комментарии ниже):

Вариант 2 (намного быстрее):

в настоящее время принятый ответ неверен о том, что innerHTML медленнее (по крайней мере, в IE и Chrome), Как правильно упоминалось m93a.

Chrome и FF значительно быстрее, используя этот метод (который уничтожит прикрепленные данные jquery):

в отдаленную секунду для FF и Chrome, и самый быстрый в IE:

innerHTML будет не уничтожит ваши обработчики событий или сломает ссылки jquery, он также рекомендуется в качестве решения здесь: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML

самый быстрый метод манипуляции DOM (все еще медленнее, чем предыдущие два) — удаление диапазона, но диапазоны не поддерживаются до IE9.

другие упомянутые методы кажутся сопоставимыми, но намного медленнее, чем innerHTML, за исключением выброса, jquery (1.1.1 и 3.1.1), который значительно медленнее, чем что-либо еще:

"per-test-loop" Jsperf часто понимается как "per-iteration", и только первая итерация имеет узлы для удаления, поэтому результаты бессмысленны, во время публикации были неправильно настроены тесты в этом потоке.

Читайте также:  Xiaomi redmi note 3 pro быстрая зарядка

если есть шанс, что у вас есть jQuery пострадавших потомков, то вы должны используйте некоторый метод, который очистит данные jQuery.

в jQuery .empty() метод гарантирует, что все данные, связанные с удаляемыми элементами jQuery, будут очищены.

если вы просто использовать DOM методы удаления детей, что данные останутся.

Модификации DOM – это ключ к созданию «живых» страниц.

Здесь мы увидим, как создавать новые элементы «на лету» и изменять уже существующие.

Пример: показать сообщение

Рассмотрим методы на примере – а именно, добавим на страницу сообщение, которое будет выглядеть получше, чем alert .

Это был пример HTML. Теперь давайте создадим такой же div , используя JavaScript (предполагаем, что стили в HTML или во внешнем CSS-файле).

Создание элемента

DOM-узел можно создать двумя методами:

Создаёт новый элемент с заданным тегом:

Создаёт новый текстовый узел с заданным текстом:

Создание сообщения

В нашем случае сообщение – это div с классом alert и HTML в нём:

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

Методы вставки

Чтобы наш div появился, нам нужно вставить его где-нибудь в document . Например, в document.body .

Для этого есть метод append , в нашем случае: document.body.append(div) .

Вот полный пример:

Вот методы для различных вариантов вставки:

  • node.append(. nodes or strings) – добавляет узлы или строки в конец node ,
  • node.prepend(. nodes or strings) – вставляет узлы или строки в начало node ,
  • node.before(. nodes or strings) –- вставляет узлы или строки до node ,
  • node.after(. nodes or strings) –- вставляет узлы или строки после node ,
  • node.replaceWith(. nodes or strings) –- заменяет node заданными узлами или строками.

Вот пример использования этих методов, чтобы добавить новые элементы в список и текст до/после него:

Наглядная иллюстрация того, куда эти методы вставляют:

Итоговый список будет таким:

Эти методы могут вставлять несколько узлов и текстовых фрагментов за один вызов.

Например, здесь вставляется строка и элемент:

Весь текст вставляется как текст.

Поэтому финальный HTML будет:

Другими словами, строки вставляются безопасным способом, как делает это elem.textContent .

Поэтому эти методы могут использоваться только для вставки DOM-узлов или текстовых фрагментов.

А что, если мы хотим вставить HTML именно «как html», со всеми тегами и прочим, как делает это elem.innerHTML ?

insertAdjacentHTML/Text/Element

С этим может помочь другой, довольно универсальный метод: elem.insertAdjacentHTML(where, html) .

Первый параметр – это специальное слово, указывающее, куда по отношению к elem производить вставку. Значение должно быть одним из следующих:

  • "beforebegin" – вставить html непосредственно перед elem ,
  • "afterbegin" – вставить html в начало elem ,
  • "beforeend" – вставить html в конец elem ,
  • "afterend" – вставить html непосредственно после elem .

Второй параметр – это HTML-строка, которая будет вставлена именно «как HTML».

Так мы можем добавлять произвольный HTML на страницу.

Мы можем легко заметить сходство между этой и предыдущей картинкой. Точки вставки фактически одинаковые, но этот метод вставляет HTML.

Читайте также:  S42ax yb11 автономный режим

У метода есть два брата:

  • elem.insertAdjacentText(where, text) – такой же синтаксис, но строка text вставляется «как текст», вместо HTML,
  • elem.insertAdjacentElement(where, elem) – такой же синтаксис, но вставляет элемент elem .

Они существуют, в основном, чтобы унифицировать синтаксис. На практике часто используется только insertAdjacentHTML . Потому что для элементов и текста у нас есть методы append/prepend/before/after – их быстрее написать, и они могут вставлять как узлы, так и текст.

Так что, вот альтернативный вариант показа сообщения:

Удаление узлов

Для удаления узла есть методы node.remove() .

Например, сделаем так, чтобы наше сообщение удалялось через секунду:

Если нам нужно переместить элемент в другое место – нет необходимости удалять его со старого.

Все методы вставки автоматически удаляют узлы со старых мест.

Например, давайте поменяем местами элементы:

Клонирование узлов: cloneNode

Как вставить ещё одно подобное сообщение?

Мы могли бы создать функцию и поместить код туда. Альтернатива – клонировать существующий div и изменить текст внутри него (при необходимости).

Иногда, когда у нас есть большой элемент, это может быть быстрее и проще.

  • Вызов elem.cloneNode(true) создаёт «глубокий» клон элемента – со всеми атрибутами и дочерними элементами. Если мы вызовем elem.cloneNode(false) , тогда клон будет без дочерних элементов.

Пример копирования сообщения:

DocumentFragment

DocumentFragment является специальным DOM-узлом, который служит обёрткой для передачи списков узлов.

Мы можем добавить к нему другие узлы, но когда мы вставляем его куда-то, он «исчезает», вместо него вставляется его содержимое.

Например, getListContent ниже генерирует фрагмент с элементами
, которые позже вставляются в

    :

Обратите внимание, что на последней строке с (*) мы добавляем DocumentFragment , но он «исчезает», поэтому структура будет:

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

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

Устаревшие методы вставки/удаления

Есть несколько других, более старых, методов вставки и удаления, которые существуют по историческим причинам.

Сейчас уже нет причин их использовать, так как современные методы append , prepend , before , after , remove , replaceWith более гибкие и удобные.

Мы упоминаем о них только потому, что их можно найти во многих старых скриптах:

Добавляет node в конец дочерних элементов parentElem .

Следующий пример добавляет новый
в конец

    :

Вставляет node перед nextSibling в parentElem .

Следующий пример вставляет новый элемент перед вторым
:

Чтобы вставить newLi в начало, мы можем сделать вот так:

Заменяет oldChild на node среди дочерних элементов parentElem .

Удаляет node из parentElem (предполагается, что он родитель node ).

Этот пример удалит первый
из

    :

Все эти методы возвращают вставленный/удалённый узел. Другими словами, parentElem.appendChild(node) вернёт node . Но обычно возвращаемое значение не используют, просто вызывают метод.

Несколько слов о «document.write»

Есть ещё один, очень древний метод добавления содержимого на веб-страницу: document.write .

Читайте также:  Управление шаговым двигателем с компьютера

Вызов document.write(html) записывает html на страницу «прямо здесь и сейчас». Строка html может быть динамически сгенерирована, поэтому метод достаточно гибкий. Мы можем использовать JavaScript, чтобы создать полноценную веб-страницу и записать её в документ.

Этот метод пришёл к нам со времён, когда ещё не было ни DOM, ни стандартов… Действительно старые времена. Он всё ещё живёт, потому что есть скрипты, которые используют его.

В современных скриптах он редко встречается из-за следующего важного ограничения:

Вызов document.write работает только во время загрузки страницы.

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

Так что после того, как страница загружена, он уже непригоден к использованию, в отличие от других методов DOM, которые мы рассмотрели выше.

Это его недостаток.

Есть и преимущество. Технически, когда document.write запускается во время чтения HTML браузером, и что-то пишет в документ, то браузер воспринимает это так, как будто это изначально было частью загруженного HTML-документа.

Поэтому он работает невероятно быстро, ведь при этом нет модификации DOM. Метод пишет прямо в текст страницы, пока DOM ещё в процессе создания.

Так что, если нам нужно динамически добавить много текста в HTML, и мы находимся на стадии загрузки, и для нас очень важна скорость, это может помочь. Но на практике эти требования редко сочетаются. И обычно мы можем увидеть этот метод в скриптах просто потому, что они старые.

Итого

Методы для создания узлов:

  • document.createElement(tag) – создаёт элемент с заданным тегом,
  • document.createTextNode(value) – создаёт текстовый узел (редко используется),
  • elem.cloneNode(deep) – клонирует элемент, если deep==true , то со всеми дочерними элементами.

Вставка и удаление:

  • node.append(. nodes or strings) – вставляет в node в конец,
  • node.prepend(. nodes or strings) – вставляет в node в начало,
  • node.before(. nodes or strings) –- вставляет прямо перед node ,
  • node.after(. nodes or strings) –- вставляет сразу после node ,
  • node.replaceWith(. nodes or strings) –- заменяет node .
  • node.remove() –- удаляет node .
  • parent.appendChild(node)
  • parent.insertBefore(node, nextSibling)
  • parent.removeChild(node)
  • parent.replaceChild(newElem, node)

Все эти методы возвращают node .

Если нужно вставить фрагмент HTML, то elem.insertAdjacentHTML(where, html) вставляет в зависимости от where :

  • "beforebegin" – вставляет html прямо перед elem ,
  • "afterbegin" – вставляет html в elem в начало,
  • "beforeend" – вставляет html в elem в конец,
  • "afterend" – вставляет html сразу после elem .

Также существуют похожие методы elem.insertAdjacentText и elem.insertAdjacentElement , они вставляют текстовые строки и элементы, но они редко используются.

Чтобы добавить HTML на страницу до завершения её загрузки:

После загрузки страницы такой вызов затирает документ. В основном встречается в старых скриптах.

Задачи

createTextNode vs innerHTML vs textContent

У нас есть пустой DOM-элемент elem и строка text .

Какие из этих 3-х команд работают одинаково?

  1. elem.append(document.createTextNode(text))
  2. elem.innerHTML = text
  3. elem.textContent = text

решение

Ответ: 1 и 3.

Результатом обеих команд будет добавление text «как текст» в elem .