Ответ 1
removeChild
следует вызывать у родителя, то есть:
parent.removeChild(child);
В вашем примере вы должны делать что-то вроде:
if (frameid) {
frameid.parentNode.removeChild(frameid);
}
Я пытаюсь проверить, существует ли элемент 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 content into the DOM
my_div = document.getElementById("debug");
document.body.insertBefore(iframe, my_div);
}
Проверка того, существует ли он, работает, создавая элемент, но удаление этого элемента не выполняется. В принципе, весь этот код вводит iframe в веб-страницу, нажав кнопку. Я бы хотел, чтобы iframe уже там, чтобы удалить его. Но по какой-то причине я терплю неудачу.
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 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 root node, so let 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();
Кажется, мне не хватает репутации, чтобы опубликовать комментарий, так что еще один ответ должен будет сделать.
Когда вы отсоединяете node с помощью removeChild() или устанавливаете свойство innerHTML для родителя, вам также необходимо убедиться, что нет ничего другого, ссылающегося на него, иначе он фактически не будет уничтожен и приведет к утечке памяти. Существует множество способов, с помощью которых вы могли бы ссылаться на node перед вызовом removeChild(), и вы должны убедиться, что те ссылки, которые не вышли из области действия, явно удалены.
Doug Crockford пишет здесь, что обработчики событий известны как причина циклических ссылок в 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. Но из-за плохой поддержки браузера вы не должны его использовать.
Но вы можете использовать метод remove, если вы используете jQuery...
$('#left-section').remove(); //using remove method in jQuery
Также в новых средах, таких как вы можете использовать условия для удаления элемента, например *ngIf
в Angular и в React, рендеринг разных представлений зависит от условий...