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

ここに 2 つの答えがあります。1 つはこの特定のケース (使用しているwaitForKeyElements) 用で、もう 1 つは一般的なケース用です。

この特定のケースでは:

既に使用し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. Have wrapImportantWordsreturn 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. ノードが削除されたことを検出したい場合は、そのにオブザーバーを設定する必要があります。ノード自体が削除されているか、完全に書き換えられている場合、ミューテーション レコードは使用できないようです。
    この場合、 がいつspan.myclass2削除されるかを知りたいので、その親 ( span.myclass) を観察します。
  2. Mutation Summaryライブラリは、これを容易にすると言われています。

完全な 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 に答える