В JavaScript можно создавать элементы с нуля и добавлять их в уже существующую html-разметку (см. статью "Создание html-элементов в JavaScript"). Однако нередко возникает вопрос - а как удалить уже существующие html-элементы? Давайте рассмотрим способы.
Удаление html-элементов методом removeChild()
Метод removeChild() существует достаточно давно, поэтому им стоит пользоваться там, где нужна поддержка старых браузеров. Однако с ним стоит быть внимательным, т.к. "удалить ребенка" (именно так переводится этот метод с английского) можно только у его родителя. Т.е. при использовании этого метода код будет такой:
1 | element.parentNode.removeChild(element) |
Давайте рассмотрим удаление элементов на примере списка:
1 2 3 4 5 6 7 8 | let li = document.querySelectorAll('#testUl li'); for (var i = 0, len = li.length; i < len; i++) { li[i].onclick = function() { console.log('parentNode', this.parentNode); console.log('element => this', this); this.parentNode.removeChild(this); } } |
В этом примере мы назначаем обработчик клика каждому элементу <li>
списка <ul id="testUl">
и в нем удаляем этот элемент <li>
. Посмотрите, насколько запутанной получилась строчка this.parentNode.removeChild(this)
. Тем не менее интерпретатор JavaScript браузера ее отлично понимает, т.к. мы говорим ему, что нужно сначала найти родительский узел этого элемента <li>
(this.parentNode
), т.е. <ul>
, а затем удалить дочерний узел с именно этим элементом (removeChild(this)
). Для того чтобы убедиться, кто родитель, кто потомок, мы используем console.log()
для просмотра элементов:
Попробуйте сами:
- Элемент списка 1
- Элемент списка 2
- Элемент списка 3
- Элемент списка 4
- Элемент списка 5
Удаление методом remove()
По сравнению с removeChild()
метод remove() прост и понятен:
1 | element.remove() |
Т.е. все, что вам нужно сделать - это обратиться к элементу и вызвать метод remove()
. Рассмотрим его также на примере, в котором по клику будут исчезать однотипные html-блоки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <style> .myblock { display: inline-block; width: 150px; height: 150px; border: 2px solid #444; background-color: #2a30b2; text-align: center; color: #fff; padding: 10px; margin: 8px; cursor: pointer; } .myblock:nth-child(2) { background-color: #bc0b0b; } .myblock:nth-child(3) { background-color: #057e21; } .myblock:nth-child(4) { background-color: #dd04cc; } </style> <div class="test"> <div class="myblock"> <h3>Исчезающий блок 1</h3> </div> <div class="myblock"> <h3>Исчезающий блок 2</h3> </div> <div class="myblock"> <h3>Исчезающий блок 3</h3> </div> <div class="myblock"> <h3>Исчезающий блок 4</h3> </div> </div> <script> let myblock = document.querySelectorAll('.myblock'); myblock.forEach(block => block.addEventListener('click', removeBlock)); function removeBlock() { let block = this; block.style.opacity = 1; let blockId = setInterval(function() { if (block.style.opacity > 0) block.style.opacity -= .1; else { clearInterval(blockId); block.remove(); } }, 60) } </script> |
В этом примере использован метод setInterval()
для формирования постепенного исчезновения блока.
Исчезающий блок 1
Исчезающий блок 2
Исчезающий блок 3
Исчезающий блок 4
Поскольку метод remove() относится к новому стандарту, он совсем не поддерживается в Internet Explorer (до 11 версии включительно), Opera Mini (она вообще мало, что поддерживает из новых стандартов), а в более прогрессивных Chrome & Firefox поддержка есть с 23 версии, в Opera - с 15, в Safari - с 7, т.е. примерно с 2012 года. Более полная информация - на сайте caniuse.com:
Для браузеров, не поддерживающих данный метод (и ряд других), можно использовать полифилы DOM4 или DOMShim.
Удаление всех элементов внутри родителя
Часто бывает такая ситуация, что внутри родительского элемента необходимо удалить все узлы-потомки. Например, в том же списке нужно оставить <ul>
или <ol>
с каким-либо id
, но удалить все вложенные <li>
. Для этого можно воспользоваться свойством innerHTML
или innerText
, или же textContent
, присвоив в него пустую строку:
1 2 3 4 5 | someElem.innerHTML = ''; //или someElem.innerText = ''; //или someElem.textContent= ''; |
Этот способ сработает достаточно быстро, но в некоторых браузерах будет быстрее вариант с удалением всех узлов элемента при отслеживании наличия у него вложенных элементов-потомков, или детей. Это можно сделать несколькими способами:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | while (node.firstChild) { node.removeChild(node.firstChild); } //или while (node.lastChild) { node.removeChild(node.lastChild); } //или while (node.hasChildNodes()) { node.removeChild(node.lastChild); } //или с использованием метода remove() //для node.firstChild while (node.firstChild) { node.firstChild.remove(); } //для node.lastChild while (node.lastChild) { node.lastChild.remove(); } |
Переменная node
в приведенных примерах - это тот элемент (узел), в котором нужно удалить вложенные (дочерние) элементы.
В примере ниже мы используем различные виды удаления вложенных элементов списка с возможностью его восстановить и попробовать другие.
- Элемент списка 1
- Элемент списка 2
- Элемент списка 3
- Элемент списка 4
- Элемент списка 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <div class="test"> <ul id="forRemove"> <li>Элемент списка 1</li> <li>Элемент списка 2</li> <li>Элемент списка 3</li> <li>Элемент списка 4</li> <li>Элемент списка 5</li> </ul> <fieldset style="margin: 10px 0"> <legend>Заменить пустой строкой</legend> <button class="btn" onclick="forRemove.innerHTML = ''">innerHTML</button> <button class="btn" onclick="forRemove.innerText = ''">innerText</button> <button class="btn" onclick="forRemove.textContent = ''">textContent</button> </fieldset> <button class="btn btn-primary" id="reList" onclick="myNode.innerHTML = liElems">Вернуть список</button> <button class="btn" onclick="removeLiElements()">Удалить все элементы li</button> <script> var myNode = document.getElementById("forRemove"), liElems = myNode.innerHTML; function removeLiElements() { while (myNode.firstChild) { myNode.removeChild(myNode.firstChild); } } </script> |
Удаление элементов в jQuery
В jQuery один элемент вы удаляете с помощью метода remove(), а для удаления всех вложенных элементов есть метод empty(). Само собой, что вы должны сначала подключить эту библиотеку, скачав ее на оффсайте или используя CDN. При использовании обоих методов все данные, включая обработчики событий, удаляются вместе с элементом.
Пример с использованием методов jQuery remove() и empty()
Давайте используем оба метода jQuery - remove() и empty() - в примере: при клике на любом из абзацев вы удаляете только этот абзац, при клике на кнопке - удаляете все содержимое <div id="myDiv">
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <div id="myDiv"> <p>Текст 1-го абзаца внутри div#myDiv</p> <p>Текст 2-го абзаца внутри div#myDiv</p> <p>Текст 3-го абзаца внутри div#myDiv</p> <button class="btn btn-primary" id="clearDiv">Очистить div</button> </div> <script> (function($) { $('#myDiv p').on('click', function() { $(this).remove(); }); $('#clearDiv').on('click', function() { $('#myDiv').empty(); }); })(jQuery); </script> |
Попробуйте сами:
Текст 1-го абзаца внутри div#myDiv
Текст 2-го абзаца внутри div#myDiv
Текст 3-го абзаца внутри div#myDiv
Метод jQuery elem.detach()
Можно также использовать метод detach(), который не удаляет данные и обработчики событий вместе с элементами. Он хорош в том случае, если вы планируете после каких-либо действий вернуть элементы на свое бывшее или в другое место. Например, мы можем перемещать ul
между 2-мя блоками, используя метод detach()
для удаления списка из первого элемента и метод appendTo()
для добавления этого списка во второй блок. Удаленный список мы сохраняем в переменную, которую используем при добавлении списка во второй, а затем и в первый блок. При этом можно заметить, что при клике на элементах li
нашего перемещаемого списка срабатывают собственные события клика, которые изменяют его внешний вид за счет добавления/удаления класса different
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <style> #full, #empty { display: inline-block; margin: 7px; width: 40%; padding: 10px; border: 2px dotted #154574; cursor: pointer; } #full {background-color: #a8bcff;} #empty {background-color: #a8daff;} .different {background-color: #092ca2; color: #fff;} </style> <div id="full"> <h3>Первый</h3> <ul id="myUl"> <li>Lorem ipsum dolor sit.</li> <li>Obcaecati distinctio deserunt mollitia.</li> <li>Magni omnis, odit iure?</li> <li>Saepe, eum delectus eius!</li> </ul> </div> <div id="empty"> <h3>Второй</h3> </div> <script> (function($) { let ul=null; $('#full').on('click', function() { if($(this).find('*').is('#myUl')) ul = $('#myUl').detach(); else ul.appendTo($(this)); }); $('#empty').on('click', function() { ul.appendTo($(this)); }); $('#myUl li').click(function(){ $(this).toggleClass('different'); }); })(jQuery); </script> |
Поэкспериментируйте самостоятельно, кликая то на первом, то на втором блоке.
Первый
- Lorem ipsum dolor sit.
- Obcaecati distinctio deserunt mollitia.
- Magni omnis, odit iure?
- Saepe, eum delectus eius!
Второй
В jQuery также можно удалить вложенные элементы и такими способами:
1 2 3 | elem.children().remove(); //или elem.html(""); |
Пример с удалением и скрытием/отображением элемента
Допустим вам нужно удалить некий div с анимацией, которая запускается по клику на этом div-е и всего один раз. Для одноразовой обработки собвтия можно использовать событие jQuery one() или метод addEventListener('click', function(){ }, {once: true})
- в конце важно указать {once: true}
. Для удаления div-а используем метод remove()
, который есть как в нативном JavaScript, так и jQuery, а скрыть/показать элемент можно простым переключением между добавлением/удалением класса hidden с единственным свойством display: none
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <style> #animation { width: 400px; margin: 20px auto; position: relative; text-align: center; } #frame { width: 50px; height: 72px; margin: 15px auto; border: 1px solid transparent; background: url(https://s.cdpn.io/79/sprite-steps.png) no-repeat left top; } @keyframes frame-animation { 0% { background-position: 0px 0; } 100% { background-position: -500px 0; } } .hidden {display: none;} </style> <div class="test"> <div id="animation"> <div id="frame"></div> <button class="button" id="showHide">Показать/спрятать</button> <button class="button" id="removeDiv">Удалить div совсем</button> </div> <script> frame.addEventListener('click', function(){ this.style.animation = 'frame-animation 1s steps(10) infinite'; }, {once: true}) showHide.addEventListener('click', function(){ frame.classList.toggle('hidden'); }) removeDiv.addEventListener('click', function(){ frame.remove(); }) </script> </div> |
Протестировать пример можно прямо сейчас. Для запуска анимации щелкните на картинке.
Подскажите а как удалить елемент списка созданого в JS
var li = document.createElement('li');
li.innerHTML =
...
li.remove();
Интересно а как удалить именно div а не только текст, или как запретить использовать кнопку много раз ? В моём коде идёт анимация после нажатия на div и если нажать ещё раз то создается дубликат этой анимации.
Привет
Привет.
Посмотрите пример в конце статьи - возможно вам поможет.