jquery 防止从DOM中删除节点

goucqfw6  于 2023-05-28  发布在  jQuery
关注(0)|答案(2)|浏览(174)

我想防止一个元素被删除通过使用类似preventDefault()的东西。前任

myNode.on("remove", (e) => {
       e.preventDefault();
    });

我可以通过使用MutationObserver来检测删除,但我不能阻止元素被删除。感谢你的帮助。🙏

j2cgzkjk

j2cgzkjk1#

你不能。没有触发事件(除了不推荐的突变事件,它们是不可取消的),突变观察器不能阻止它发生,等等。
您可以检测到它发生并将其放回,但您无法阻止特定的一个被删除。
这里有一个简单的例子在本例中,代码假定它应该位于其父对象的顶部,但当然这并不总是正确的。如果您必须将其插入某个特殊的位置,则需要在取出之前知道它的位置。

const observer = new MutationObserver(records => {
    for (const {target, removedNodes} of records) {
        const element = Array.prototype.find.call(removedNodes, ({id}) => id === "the-element");
        if (element) {
            console.log("Re-inserted at top of parent");
            target.insertBefore(element, target.firstChild);
        }
    }
});
observer.observe(document.body, {
    subtree: true,
    childList: true
});
document.getElementById("the-btn").addEventListener("click", () => {
    document.getElementById("the-element").remove();
});
<div>
  <div id="the-element">this is the element</div>
  <input id="the-btn" type="button" value="Remove It">
</div>
ymzxtsji

ymzxtsji2#

注意Object.freeze/Object.seal不会阻止节点删除。这在Mozilla的知识库中没有明确提到:

arguments[1] = HTMLDocument.prototype.createElement.call(document, "style")

Node.prototype.appendChild.call(document.head, arguments[1])

Object.freeze(arguments[1])

HTMLElement.prototype.remove.call(arguments[1]) // gone

如果您在访问页面时将css插入到DOM中以修改它们的外观,但某些页面会扰乱“DOMContentLoaded”上的样式,并将删除您的样式,则会出现问题。使用javascript这不是问题,因为你可以简单地对它进行eval或“importScripts”,不需要向DOM添加任何东西,但使用css这是一个问题。所以你必须注意你的css样式或者你使用MutationObserver添加的任何其他节点。给予你的节点一个显式的className,并监视MutationObserver回调中的变化。示例:

Array.prototype.forEach.call(arguments[0], function()
{
    if (Object.prototype.toString.call(arguments[0].addedNodes[0]) == "[object HTMLHeadElement]" || (Object.prototype.toString.call(arguments[0].removedNodes[0]) == "[object HTMLStyleElement]" && arguments[0].removedNodes[0].className == "myFancyStyle") || (Object.prototype.toString.call(arguments[0].target) == "[object HTMLStyleElement]" && arguments[0].target.className == "myFancyStyle"))
    {
        /*
            if document.head has just been added to the dom, attach your style to it

            if your style has been removed (arguments[0].removedNodes[0]), re-add it

            if your style has been messed with (arguments[0].target), remove the style first, who knows what the website did to it, then re-add it

            If you are re-adding it, better set a setTimeout of 0 to wait for a frame, because if the website script is looping thru a NodeList and you insert another node during their loop, you'll break their iteration !
        */
    }
})

相关问题