简体   繁体   English

JavaScript DOM 移除元素

[英]JavaScript DOM remove element

I'm trying to test if a DOM element exists, and if it does exist delete it, and if it doesn't exist create it.我正在尝试测试 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);
}

Checking if it exists works, creating the element works, but deleting the element doesn't.检查它是否存在有效,创建元素有效,但删除元素无效。 Basically all this code does is inject an iframe into a webpage by clicking a button.基本上这段代码所做的就是通过单击一个按钮将 iframe 注入网页。 What I would like to happen is if the iframe is already there to delete it.我想要发生的是,如果 iframe 已经在那里删除它。 But for some reason I am failing.但由于某种原因,我失败了。

removeChild should be invoked on the parent, ie: removeChild应该在父级上调用,即:

parent.removeChild(child);

In your example, you should be doing something like:在您的示例中,您应该执行以下操作:

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

In most browsers, there's a slightly more succinct way of removing an element from the DOM than calling .removeChild(element) on its parent, which is to just call element.remove() .在大多数浏览器中,从 DOM 中删除元素的方法比在其父.removeChild(element)上调用.removeChild(element)更简洁,即调用element.remove() In due course, this will probably become the standard and idiomatic way of removing an element from the DOM.在适当的时候,这可能会成为从 DOM 中删除元素的标准和惯用方法。

The .remove() method was added to the DOM Living Standard in 2011 ( commit ), and has since been implemented by Chrome, Firefox, Safari, Opera, and Edge. .remove()方法于 2011 年被添加到 DOM Living Standard ( commit ) 中,此后被 Chrome、Firefox、Safari、Opera 和 Edge 实现。 It was not supported in any version of Internet Explorer.任何版本的 Internet Explorer 都不支持它。

If you want to support older browsers, you'll need to shim it.如果您想支持较旧的浏览器,则需要对其进行填充。 This turns out to be a little irritating, both because nobody seems to have made a all-purpose DOM shim that contains these methods, and because we're not just adding the method to a single prototype;事实证明这有点令人恼火,因为似乎没有人制作包含这些方法的通用 DOM shim,而且因为我们不只是将方法添加到单个原型; it's a method of ChildNode , which is just an interface defined by the spec and isn't accessible to JavaScript, so we can't add anything to its prototype.它是ChildNode的一个方法,它只是规范定义的一个接口,JavaScript 无法访问,因此我们无法在其原型中添加任何内容。 So we need to find all the prototypes that inherit from ChildNode and are actually defined in the browser, and add .remove to them.所以我们需要找到所有继承自ChildNode的原型,并在浏览器中实际定义,并在其中添加.remove

Here's the shim I came up with, which I've confirmed works in IE 8.这是我想出的垫片,我已经确认它在 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;
        }
    }
})();

This won't work in IE 7 or lower, since extending DOM prototypes isn't possible before IE 8 .这在 IE 7 或更低版本中不起作用,因为在 IE 8 之前扩展 DOM 原型是不可能的 I figure, though, that on the verge of 2015 most people needn't care about such things.不过,我认为,在 2015 年即将到来之际,大多数人不需要关心这些事情。

Once you've included them shim, you'll be able to remove a DOM element element from the DOM by simply calling一旦你包含了它们,你就可以通过简单地调用从 DOM 中删除一个 DOM 元素element

element.remove();

Seems I don't have enough rep to post a comment, so another answer will have to do.似乎我没有足够的代表发表评论,所以必须做另一个答案。

When you unlink a node using removeChild() or by setting the innerHTML property on the parent, you also need to make sure that there is nothing else referencing it otherwise it won't actually be destroyed and will lead to a memory leak.当您使用 removeChild() 或通过在父节点上设置 innerHTML 属性取消链接节点时,您还需要确保没有其他任何内容引用它,否则它实际上不会被销毁并导致内存泄漏。 There are lots of ways in which you could have taken a reference to the node before calling removeChild() and you have to make sure those references that have not gone out of scope are explicitly removed.在调用 removeChild() 之前,您可以通过多种方式获取对节点的引用,并且您必须确保那些没有超出范围的引用被显式删除。

Doug Crockford writes here that event handlers are known a cause of circular references in IE and suggests removing them explicitly as follows before calling 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]);
        }
    }
}

And even if you take a lot of precautions you can still get memory leaks in IE as described by Jens-Ingo Farley here .即使您采取了很多预防措施,您仍然可能会在 IE 中出现内存泄漏,如 Jens-Ingo Farley此处所述

And finally, don't fall into the trap of thinking that Javascript delete is the answer.最后,不要陷入认为 Javascript删除就是答案的陷阱。 It seems to be suggested by many, but won't do the job.许多人似乎建议这样做,但不会完成这项工作。 Here is a great reference on understanding delete by Kangax.这里是了解 Kangax删除的一个很好的参考。

Using Node.removeChild() does the job for you, simply use something like this:使用Node.removeChild()为您完成这项工作,只需使用以下内容:

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

In DOM 4, the remove method applied, but there is a poor browser support according to W3C:在 DOM 4 中,应用了 remove 方法,但根据 W3C 的浏览器支持很差:

The method node.remove() is implemented in the DOM 4 specification.方法 node.remove() 在 DOM 4 规范中实现。 But because of poor browser support, you should not use it.但由于浏览器支持不佳,您不应该使用它。

But you can use remove method if you using jQuery...但是如果你使用 jQuery,你可以使用 remove 方法......

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

Also in new frameworks like you can use conditions to remove an element, for example *ngIf in Angular and in React, rendering different views, depends on the conditions...同样在新框架中,您可以使用条件来删除元素,例如在 Angular 和 React 中使用*ngIf ,呈现不同的视图,取决于条件......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM