javascript - 如何使用 jQuery 检测 HTML 元素是否消失?

标签 javascript jquery greasemonkey userscripts mutation-observers

在用户脚本中,我使用 waitForKeyElements() 对元素变化进行了大量检测。 .
但是,我遇到了一个特定示例,其中 waitForKeyElements 不能可靠地触发更改。
我的用户脚本调整 theirID 以插入内部跨度,如您在此处看到的:

<span id='theirID' class='myclass'>
  <span class='myclass2'>text</span> more text
</span>

该网站然后更改此代码以删除我的内部跨度,因此它看起来像:

<span id='theirID' class='myclass'>
  some text
</span>

出于某种原因,在某些情况下,waitForKeyElements 不会因该更改而被触发。我尝试检测外部跨度、内部跨度、外部跨度的父级、其父级等的变化。

所以我现在想知道是否有其他方法可以检测,例如,带有 myclass2 的元素(内部跨度)是否已经消失?我想我可以轮询 $('.myclass2').length,但我不知道它从文档中的什么地方消失了。理想情况下,我会知道持有现在丢失的元素的具体 parent 。

有什么想法吗?

最佳答案

这里有两个答案,一个针对这种特定情况(您正在使用 waitForKeyElements),另一个针对一般情况。

对于这个特定案例:

由于您已经在使用 waitForKeyElements(),您可以利用节点处理程序中的返回值。

假设目标页面最初有这样的 HTML:

<span id='theirID1' class='myclass'>
    Original text 1.
</span>

并且您的脚本使用了 waitForKeyElements(),如下所示:

waitForKeyElements ("span.myclass", wrapImportantWords);

function wrapImportantWords (jNode) {
    var newContent  = jNode.text ().replace (/Original/ig, "<span class='myclass2'>My GM</span>");
    jNode.html (newContent);
}

产量:

<span class="myclass" id="theirID1">
    <span class="myclass2">My GM</span> text 1.
</span>


然后,您可以:

  1. wrapImportantWords 返回 true -- 这告诉 waitForKeyElements 最终没有找到该节点,因此它会继续检查。
  2. 让该函数同时检查是否(仍然)存在适当的 span.myclass2

像这样:

waitForKeyElements ("span.myclass", wrapImportantWords);

function wrapImportantWords (jNode) {
    if (jNode.has ("span.myclass2").length == 0) {
        var newContent  = jNode.text ().replace (/Original/ig, "<span class='myclass2'>My GM</span>");
        jNode.html (newContent);
    }
    return true;
}


通常使用新的 MutationObserver 检测消失的元素:

在您的具体情况下,这似乎有点矫枉过正。但是,这里有一个方法供一般引用。

注意事项:

  1. 如果你想检测一个节点被删除,你必须在它的parent上设置观察者。当节点本身被删除或完全重写时,突变记录似乎不可用。
    在这种情况下,我们想知道 span.myclass2 何时被删除,因此我们观察它们的父级 (span.myclass)。
  2. > The Mutation Summary library据称使这更容易。

这里是一个完整的 Firefox Greasemonkey 脚本。您可以针对 this page 进行测试. (请注意,Chrome 代码是相同的,除了由于缺少 @require 而进行的常规更改。)

// ==UserScript==
// @name     _Node watcher 1
// @include  http://jsbin.com/exigal/*
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change introduced
    in GM 1.0.   It restores the sandbox.
*/

waitForKeyElements ("span.myclass", wrapImportantWords);

function wrapImportantWords (jNode) {
    var newContent  = jNode.text ().replace (
        /Original/ig, "<span class='myclass2'>My GM</span>"
    );
    jNode.html (newContent);
}

/*--- Start of Mutation observer code...
*/
var targetNodes      = $("span.myclass");
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var myObserver       = new MutationObserver (mutationHandler);
var obsConfig        = {
    childList: true, characterData: true, attributes: true, subtree: true
};

//--- Add a target node to the observer. Can only add one node at a time.
targetNodes.each ( function () {
    myObserver.observe (this, obsConfig);
} );

function mutationHandler (mutationRecords) {

    mutationRecords.forEach ( function (mutation) {

        if (    mutation.type                == "childList"
            &&  typeof mutation.removedNodes == "object"
        ) {
            var remdNodes       = $(mutation.removedNodes);
            if (remdNodes.is ("span.myclass2") ) {
                console.log ("Desired node was deleted!   Restoring...");
                var targNode    = $(mutation.target);
                wrapImportantWords (targNode);
            }
        }
    } );
}

关于javascript - 如何使用 jQuery 检测 HTML 元素是否消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12589524/

相关文章:

javascript - 从 Greasemonkey 脚本注入(inject) document.write 调用不会导致任何加载

javascript - 从 JQuery 到 Javascript 代码

javascript - 如何在 Python 线程或子进程中访问 DOM

javascript - Javascript 中的 For 循环在另一个 for 循环中崩溃

javascript - 基于文本使用 Jquery 选择选项

php - 将参数从 Ajax 传递到 PHP 文件

javascript - 使用 json_encode() 将 php 数组转为 javascript

javascript - 悬停效果与 jQuery 影响容器 div

jquery - 访问目标页面上 jQuery 的现有副本

javascript - href 在greatmokey 中不起作用