1

在用户脚本中,我使用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只是不会被该更改触发。我试图检测外部跨度、内部跨度、外部跨度的父级、其父级等的变化。

所以我现在想知道是否有其他方法可以检测,例如,元素 w/ myclass2(内部跨度)是否消失了?我想我可以投票$('.myclass2').length,但我不知道它从文件中的哪个位置消失了。理想情况下,我会知道持有现在丢失物品的特定父母。

有任何想法吗?

4

1 回答 1

2

这里有两个答案,一个针对这种特定情况(您正在使用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.myclass2s 什么时候被删除,所以我们观察它们的父母 ( span.myclass)。
  2. 据称,突变摘要使这更容易。

这是一个完整的 Firefox Greasemonkey 脚本。您可以针对此页面对其进行测试。(请注意,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);
            }
        }
    } );
}
于 2012-09-26T11:14:44.177 回答