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 уже есть, чтобы удалить его. Но по какой-то причине я терплю неудачу.

569   4  

4 ответов:

removeChild должен быть вызван на родителя, т. е.:

parent.removeChild(child);

в вашем примере, вы должны делать что-то вроде:

if (frameid) {
    frameid.parentNode.removeChild(frameid);
}

в большинстве браузеров есть немного более лаконичный способ удаления элемента из DOM, чем вызов .removeChild(element) на его родителя, который должен просто позвонить element.remove(). Со временем это, вероятно, станет стандартным и идиоматическим способом удаления элемента из DOM.

The .remove() метод был добавлен к уровню жизни DOM в 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 или ниже, так как расширения прототипов дом не возможно, до т. е. 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, как описано Йенс-Инго Фарли здесь.

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

используя узел.removeChild () делает всю работу за вас, просто используйте что-то вроде этого:

var leftSection = document.getElementById('left-section');
leftSection.parentNode.removeChild(leftSection);

в DOM 4 применяется метод remove, но есть плохая поддержка браузера в соответствии с W3C:

узел методом.remove () реализовано в спецификации DOM 4. Но из-за плохой поддержки браузера, вы не должны использовать его.

но вы можете использовать метод удаления, Если вы используете jQuery...

$('#left-section').remove(); //using remove method in jQuery

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

Comments

    Ничего не найдено.