Удалить элемент по id


1129

При удалении элемента со стандартным JavaScript вы должны сначала перейти к его родителю:

var element = document.getElementById("element-id");
element.parentNode.removeChild(element);

Необходимость сначала перейти к родительскому узлу кажется мне немного странной, есть ли причина, по которой JavaScript работает следующим образом?


534
Как сказал Джеймс, DOM не поддерживает непосредственное удаление объекта. Вы должны пойти к его родителю и удалить его оттуда. Javascript не позволяет элементу совершить самоубийство, но он допускает детоубийство ...
Марк Хендерсон

21
Есть ли причина? Ричард Фейнман говорит нет . (Ну, техническое обоснование легко увидеть, если вы написали какие-либо программы с древовидной структурой. Ребенок должен все равно сообщить об этом родителю, иначе древовидная структура может быть нарушена. Так как он должен делать это внутренне, если он предоставляет вам однострочную функцию это просто удобная функция, которую вы можете определить сами.)
kizzx2

6
Единственная причина, по которой я вижу это то, что в документе xml / xhtml всегда должен быть корневой элемент, поэтому вы не сможете удалить его, потому что у него нет родителя
Alex K

5
Мне очень нравится обходной путь Йохана , и я не уверен, почему эти функции не предоставляются изначально. Как свидетельствует количество зрителей, это очень распространенная операция.
Zaz

12
Вы можете использовать element.remove()непосредственно с ES5. Вам не нужен родитель!
Gibolt

Ответы:


659

Я знаю, что расширение встроенных функций DOM не всегда является лучшим или наиболее популярным решением, но оно прекрасно работает для современных браузеров.

Element.prototype.remove = function() {
    this.parentElement.removeChild(this);
}
NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
    for(var i = this.length - 1; i >= 0; i--) {
        if(this[i] && this[i].parentElement) {
            this[i].parentElement.removeChild(this[i]);
        }
    }
}

И тогда вы можете удалить элементы, как это

document.getElementById("my-element").remove();

или

document.getElementsByClassName("my-elements").remove();

Примечание: это решение не работает для IE 7 и ниже. Для получения дополнительной информации о расширении DOM прочитайте эту статью .

РЕДАКТИРОВАТЬ : рассмотрение моего ответа в 2019 году, node.remove()пришло на помощь и может быть использовано следующим образом (без polyfill выше):

document.getElementById("my-element").remove();

или

[...document.getElementsByClassName("my-elements")].map(n => n && n.remove());

Эти функции доступны во всех современных браузерах (кроме IE). Читайте больше на MDN .


3
Не должно ли это быть [document.getElementsByClassName ("my-elements") [0] .remove (); ] Я думаю, что функция remove () не реализована массивами. Чтобы удалить все элементы класса или любой селектор, возвращающий массив, вы должны выполнить итерацию по всем элементам и вызвать remove () для каждого.
Седат Килинк

1
@SedatKilinc, ты попробовал настоящий фрагмент? Там нет массивов , участвующих, а скорее , NodeListили HTMLCollectionкоторые являются массивом как набор элементов. Второе определение метода позволяет удалить эти «наборы элементов».
Йохан Деттмар

1
Запуск этого в консоли Chrome, кажется, удаляет только один элемент за раз при использовании document.getElementsByClassName("my-elements").remove();. Изменить: на самом деле он удаляет кучу, но требует повторного запуска, чтобы закончить. Попробуйте это на этой странице с классом "комментарий-копия".
DanielST

2
@slicedtoad ты прав, мой плохой. Я изменил функцию, чтобы цикл назад через элементы. Кажется, работает нормально. Поведение, о котором вы говорите, скорее всего, вызвано обновленными индексами.
Йохан Деттмар

1
Не делай этого. Просто удалите элементы так, как задумал язык. Любой, кто знаком с синтаксическим анализом XML, осознает необходимость обращения к родителю для удаления дочерних элементов. HTML - это расширенный набор XML (своего рода).
Hal50000

283

Crossbrowser и IE> = 11:

document.getElementById("element-id").outerHTML = "";

3
Это кажется самым простым, самым надежным и быстрым решением. Мне не нужно удалять элемент, поэтому я пропускаю последнюю строку, но это ни в коем случае не добавляет никаких накладных расходов. Примечание . Я обнаружил это, пытаясь найти $.readyальтернативу noscriptтегам, превышающим js . Чтобы использовать его так, как я хотел, я должен был обернуть его в функцию 1 мс setTimeout. Это решает все мои проблемы одновременно. Gracias.
КГВР

Имейте в виду outerHTML, все еще является новым дополнением к стандарту. Если вы ищете поддержку для любого программного обеспечения> 6 на момент написания, вам понадобится другое решение. removeФункция уже отмечались другими является подобным случаем. Как обычно, реализовать полифилл безопасно.
Супер Кот

delete elementничего не делает, так как вы не можете удалить переменные в JS, только ключи;) Убедитесь, что он не работает console.log(element)после delete element...
Иван Клешнин

2
Это немного медленнее, чем removeChild(около 6-7% в моей системе). См. Jsperf.com/clear-outerhtml-v-removechild/2
Алехандро Гарсия Иглесиас

1
Это может оставить место, где раньше был iframe, если это то, что вы пытаетесь удалить.
lacostenycoder

164

Вы можете создать removeфункцию, чтобы вам не приходилось каждый раз думать об этом:

function removeElement(id) {
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
}

12
Если вы хотите, чтобы однострочник не выходил на глобальный уровень, вы можете перейти elemна remove.elem. Таким образом, функция ссылается на себя, поэтому вам не нужно создавать другую глобальную переменную. :-)
twiz 27.12.12

4
Итак, зачем вам возвращать элем? Почему бы и нетfunction remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }
Зак Лысобей

4
@ZachL: хотя ваше решение может показаться более очевидным, оно выполняет два поиска DOM, которые работают медленнее, и чего другие решения, похоже, хотят избежать.
Wk_of_Angmar

3
Не работает. Слишком много ошибок. Это работает: var elem = document.getElementById ('id'); elem.parentNode.removeChild (эль);
Митч Матч

2
Вау, почему так сложно. Просто передайте сам элемент функции вместо строки id. Таким образом, элемент доступен во всей функции, плюс он остается одним вкладышем
Дэвид Фаринья

97

Это то, что поддерживает DOM . Поищите на этой странице слова «удалить» или «удалить», и единственное, что удаляет узел, - removeChild .


13
Это отвечает на мой первоначальный вопрос, но почему JavaScript работает так?
Заз

5
Я просто догадываюсь здесь, но я бы предположил, что это связано с управлением памятью. Родительский узел, скорее всего, содержит список указателей на дочерние узлы. Если вы просто удалили узел (без использования parent), родитель все равно будет держать указатель и вызвать утечку памяти. Таким образом, API заставляет вас вызывать функцию на родителя, чтобы удалить ребенка. это также хорошо, потому что он может пройти по дереву через дочерние узлы, вызывая remove для каждого из них, и не вытекать из памяти.
Chadams

2
Эй, ребята, хотя эта ссылка не имеет этого, я нашел это случайно. написание element.remove();будет работать. Может быть, это что-то новое. Но впервые у меня так и работает. Я думаю, что это должно было работать всегда, потому что это очень важно.
Мухаммед Умер

1
Но это не работает в IE7 и ниже. Из IE7 и ниже, remove () не работает
fanfan1609

1
Если бы мне пришлось угадывать, причина этого в том, что элементы DOM не могут удалить себя. Вы удаляете пресловутый ковер из-под его ног. Вы должны удалить его из контейнера. По крайней мере, я так думаю об этом.
PhilT

82

DOM организован в виде дерева узлов, где каждый узел имеет значение, а также список ссылок на его дочерние узлы. Таким образом, element.parentNode.removeChild(element)имитирует именно то, что происходит внутри: сначала вы переходите на родительский узел, затем удаляете ссылку на дочерний узел.

По DOM4, функция помощника предоставляется делать то же самое: element.remove(). Это работает в 87% браузеров (по состоянию на 2016 г.), но не в IE 11. Если вам требуется поддержка старых браузеров, вы можете:


2
Пожалуйста, не «модифицируйте встроенные функции DOM» .
Эмиль Бержерон

36

Для удаления одного элемента:

 var elem = document.getElementById("yourid");
 elem.parentElement.removeChild(elem);

Для удаления всех элементов с определенным именем класса:

 var list = document.getElementsByClassName("yourclassname");
 for(var i = list.length - 1; 0 <= i; i--)
 if(list[i] && list[i].parentElement)
 list[i].parentElement.removeChild(list[i]);

Это хорошо отражено в существующих ответах.
KyleMit

4
+1 Для простого примера удаления по имени класса. Это не очень хорошо отражено в других ответах
Луиза Эгглтон

Зачем if(list[i] && list[i].parentElement)нужна линия? Разве существование каждого элемента не гарантируется тем фактом, что он был возвращен getElementsByClassNameметодом?
Гидротермальный

К сожалению, насколько я знаю, существование не гарантировано, но я не знаю подробностей об этом. Я только что испытал какое-то странное неопределенное или нулевое значение один раз, и я поставил эту проверку там без дальнейшего изучения. Так что это немного взломать.
csjpeter

Должно бытьdocument.getElementsByClassName(...
Рабочий

21

Вы можете просто использовать element.remove()


13
element.remove()не является допустимым JavaScript и работает только в определенных браузерах, таких как Chrome .
Zaz

4
Джош, это настоящий javascript, за исключением того, что только Firefox и Chrome его реализовали (см. MDN)
Тим Нгуен,

10
Мой плохой, element.remove() это правильный JavaScript с DOM4 и работает во всех современных браузерах, естественно, за исключением Internet Explorer.
Заз

24
Отлично работает на FireFox и Chrome. кто заботится о IE
Арун Шарма

13
люди с рабочими местами заботятся о IE!
sqram

18

ChildNode.remove()Метод удаляет объект из дерева , которому он принадлежит.

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

Вот скрипка, которая показывает, как можно позвонить document.getElementById('my-id').remove()

https://jsfiddle.net/52kp584L/

**

Нет необходимости расширять NodeList. Уже реализовано.

**


2
Обратите внимание, это не поддерживается ни в одной версии IE!
MacroMan

1
Если вы все еще разрабатываете для IE, мне очень жаль вас.
Алекс Фалленштедт

Вы не разрабатываете для IE? Мне очень жаль ваших клиентов или клиентов.
MacroMan

13

Вы можете напрямую удалить этот элемент, используя remove()метод DOM.

вот пример:

let subsWrapper = document.getElementById("element_id");
subsWrapper.remove();
//OR directly.
document.getElementById("element_id").remove();


7

Необходимость сначала перейти к родительскому узлу кажется мне немного странной, есть ли причина, по которой JavaScript работает следующим образом?

Имя функции есть removeChild(), и как можно удалить ребенка, когда нет родителя? :)

С другой стороны, вам не всегда нужно звонить так, как вы показали. element.parentNodeявляется только помощником, чтобы получить родительский узел данного узла. Если вы уже знаете родительский узел, вы можете просто использовать его следующим образом:

Пример:

// Removing a specified element when knowing its parent node
var d = document.getElementById("top");
var d_nested = document.getElementById("nested");
var throwawayNode = d.removeChild(d_nested);

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

================================================== =======

Чтобы добавить что-то еще:

В некоторых ответах указано, что вместо использования parentNode.removeChild(child);можно использовать elem.remove();. Но, как я заметил, между этими двумя функциями есть разница, и она не упоминается в этих ответах.

Если вы используете removeChild(), он вернет ссылку на удаленный узел.

var removedChild = element.parentNode.removeChild(element); 
console.log(removedChild); //will print the removed child.

Но если вы используете elem.remove();, он не вернет вам ссылку.

var el = document.getElementById('Example');
var removedChild = el.remove(); //undefined

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

Такое поведение можно наблюдать в Chrome и FF. Я считаю, что это стоит заметить :)

Надеюсь, мой ответ добавляет ценность к вопросу и будет полезен !!


6

Функции, которые используют ele.parentNode.removeChild (ele), не будут работать для элементов, которые вы создали, но еще не вставили в HTML. Такие библиотеки, как jQuery и Prototype, разумно используют метод, подобный следующему, чтобы обойти это ограничение.

_limbo = document.createElement('div');
function deleteElement(ele){
    _limbo.appendChild(ele);
    _limbo.removeChild(ele);
}

Я думаю, что JavaScript работает так, потому что первоначальные дизайнеры DOM считали родительскую / дочернюю и предыдущую / следующую навигацию более приоритетными, чем модификации DHTML, которые так популярны сегодня. Возможность читать из одного <input type = 'text'> и записывать в другое по относительному расположению в DOM была полезна в середине 90-х, когда динамическая генерация целых HTML-форм или интерактивных элементов графического интерфейса была едва ли не мерцанием в какой-то глаз разработчика


3

Необходимость сначала перейти к родительскому узлу кажется мне немного странной, есть ли причина, по которой JavaScript работает следующим образом?

ИМХО: причина этого та же, что и в других средах: вы выполняете действие, основанное на вашей «связи» с чем-либо. Вы не можете удалить его, пока вы связаны с ним.

Как резать ветку дерева. Во время резки садитесь на сторону, ближайшую к дереву, или результат будет ... неудачным (хотя и смешным).


2

Это на самом деле происходит от FireFox ... на этот раз, IE был впереди пакета и позволил удалить элемент напрямую.

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

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

Я полагаю, что когда они поняли проблему, обходной путь заключался в том, чтобы удалить элемент через его родительский элемент, потому что, когда элемент ушел, вы теперь просто держите ссылку на родительский элемент. Это остановит всю эту неприятность, и (если, например, закрыть узел дерева узлом) будет довольно просто «застегнут».

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

Опять же, все это просто мои догадки.

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

Вероятно, на следующий день после того, как мой слуга-робот подал в суд на меня с зарплатой.


10
Я сомневаюсь, что Firefox несет ответственность за это. removeChildявляется метод DOM уровня 1 Nodeинтерфейса .
Феликс Клинг

0

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

Ссылка: http://chiragrdarji.wordpress.com/2007/03/16/removedelete-element-from-page-using-javascript-working-in-firefoxieopera/


6
Это на самом деле не отвечает на мой вопрос, и страница, на которую вы ссылаетесь, предлагает худшее решение, чем моя.
Zaz

0
// http://javascript.crockford.com/memory/leak.html
// cleans dom element to prevent memory leaks
function domPurge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        for (i = a.length - 1; i >= 0; i -= 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            domPurge(d.childNodes[i]);
       }
    }
}

function domRemove(id) {
    var elem = document.getElementById(id);
    domPurge(elem);
    return elem.parentNode.removeChild(elem);
}

-3

Это лучшая функция для удаления элемента без ошибки скрипта:

function Remove(EId)
{
    return(EObj=document.getElementById(EId))?EObj.parentNode.removeChild(EObj):false;
}

Обратите внимание на EObj=document.getElementById(EId).

Это ОДИН знак равенства нет ==.

если элемент EIdсуществует, то функция удаляет его, в противном случае возвращает false error.


4
Создает глобальную переменную.
bjb568

1
Это также худший вариант другого ответа , но с опозданием на 2 года.
Эмиль Бержерон,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.