JavaScript DOM удалить элемент
Я пытаюсь проверить, существует ли элемент DOM, и если он существует, удалите его, и если он не существует, создайте его.
var duskdawnkey = localStorage["duskdawnkey"];
var iframe = document.createElement("iframe");
var whereto = document.getElementById("debug");
var frameid = document.getElementById("injected_frame");
iframe.setAttribute("id", "injected_frame");
iframe.setAttribute("src", 'http://google.com');
iframe.setAttribute("width", "100%");
iframe.setAttribute("height", "400");
if (frameid) // check and see if iframe is already on page
{ //yes? Remove iframe
iframe.removeChild(frameid.childNodes[0]);
} else // no? Inject iframe
{
whereto.appendChild(iframe);
// add the newly created element and it's content into the DOM
my_div = document.getElementById("debug");
document.body.insertBefore(iframe, my_div);
}
Проверка, если он существует, работает, создание элемента работает, но удаление элемента - нет. По сути, весь этот код вводит iframe в веб-страницу, нажимая кнопку. Я бы хотел, чтобы iframe уже был там, чтобы удалить его. Но по какой-то причине я терплю неудачу.
4 ответа
removeChild
должен быть вызван на родителя, то есть:
parent.removeChild(child);
В вашем примере вы должны делать что-то вроде:
if (frameid) {
frameid.parentNode.removeChild(frameid);
}
В большинстве браузеров есть несколько более краткий способ удаления элемента из DOM, чем вызов .removeChild(element)
на его родителя, который должен просто позвонить element.remove()
, Со временем это, вероятно, станет стандартным и идиоматическим способом удаления элемента из DOM.
.remove()
метод был добавлен в DOM Living Standard в 2011 году ( commit), и с тех пор был внедрен в Chrome, Firefox, Safari, Opera и Edge. Это не было поддержано ни в одной версии Internet Explorer.
Если вы хотите поддерживать более старые браузеры, вам нужно это сделать. Это оказывается немного раздражающим, потому что никто, кажется, не сделал универсальную прокладку DOM, которая содержит эти методы, и потому что мы не просто добавляем метод к одному прототипу; это метод ChildNode
, который является просто интерфейсом, определенным спецификацией, и не доступен для JavaScript, поэтому мы не можем ничего добавить к его прототипу. Итак, нам нужно найти все прототипы, которые наследуются от ChildNode
и на самом деле определены в браузере, и добавить .remove
им.
Вот схема, которую я придумал, и я подтвердил, что работает в IE 8.
(function () {
var typesToPatch = ['DocumentType', 'Element', 'CharacterData'],
remove = function () {
// The check here seems pointless, since we're not adding this
// method to the prototypes of any any elements that CAN be the
// root of the DOM. However, it's required by spec (see point 1 of
// https://dom.spec.whatwg.org/#dom-childnode-remove) and would
// theoretically make a difference if somebody .apply()ed this
// method to the DOM's root node, so let's roll with it.
if (this.parentNode != null) {
this.parentNode.removeChild(this);
}
};
for (var i=0; i<typesToPatch.length; i++) {
var type = typesToPatch[i];
if (window[type] && !window[type].prototype.remove) {
window[type].prototype.remove = remove;
}
}
})();
Это не будет работать в IE 7 или ниже, так как расширение прототипов DOM невозможно до IE 8. Я полагаю, однако, что на грани 2015 года большинство людей не должно заботиться о таких вещах.
Как только вы включите их шим, вы сможете удалить элемент DOM element
из DOM, просто позвонив
element.remove();
Кажется, мне не хватает представителя, чтобы оставить комментарий, так что придется сделать еще один ответ.
Когда вы отсоединяете узел, используя removeChild() или устанавливая свойство innerHTML на родительском объекте, вам также нужно убедиться, что на него больше ничего не ссылается, иначе он фактически не будет уничтожен и приведет к утечке памяти. Есть много способов, которыми вы могли бы получить ссылку на узел перед вызовом removeChild(), и вы должны убедиться, что те ссылки, которые не вышли из области видимости, явно удалены.
Даг Крокфорд пишет здесь, что обработчики событий известны как причина циклических ссылок в IE, и предлагает явно удалить их следующим образом перед вызовом removeChild().
function purge(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) {
purge(d.childNodes[i]);
}
}
}
И даже если вы примете много мер предосторожности, вы все равно можете получить утечки памяти в IE, как описано здесь Jens-Ingo Farley.
И, наконец, не попадитесь в ловушку, думая, что удаление Javascript - это ответ. Похоже, что многие предлагают, но не будут делать эту работу. Вот отличная ссылка на понимание удаления от Kangax.
Использование Node.removeChild() сделает всю работу за вас, просто используйте что-то вроде этого:
var leftSection = document.getElementById('left-section');
leftSection.parentNode.removeChild(leftSection);
В DOM 4 применен метод удаления, но браузер плохо поддерживает W3C:
Метод node.remove() реализован в спецификации DOM 4. Но из-за плохой поддержки браузера его не стоит использовать.
Но вы можете использовать метод удаления, если вы используете jQuery...
$('#left-section').remove(); //using remove method in jQuery
Также в новых средах, таких как вы можете использовать условия для удаления элемента, например *ngIf
в Angular и в React, рендеринг разных представлений, зависит от условий...
Если вам нравится пользоваться блестящей функцией:
$("#foo").remove();
Чтобы полностью удалить элемент из DOM.
Чтобы удалить элементы без удаления данных и событий, используйте вместо этого:
$("#foo").detach();
В
.remove()
извлекает элементы из DOM. Использовать.remove()
когда вы хотите удалить сам элемент, а также все, что внутри него. Помимо самих элементов, удаляются все связанные события и данные jQuery, связанные с элементами. Чтобы удалить элементы без удаления данных и событий, используйте.detach()
вместо.