Here are two answers, one for this specific case (you're using waitForKeyElements
, and another for the general case.
For this specific case:
Since you are using waitForKeyElements()
already, you can take advantage of the return value in the node handler.
Suppose the target page originally had HTML like this:
<span id='theirID1' class='myclass'>
Original text 1.
</span>
And your script used waitForKeyElements()
like this:
waitForKeyElements ("span.myclass", wrapImportantWords);
function wrapImportantWords (jNode) {
var newContent = jNode.text ().replace (/Original/ig, "<span class='myclass2'>My GM</span>");
jNode.html (newContent);
}
Yielding:
<span class="myclass" id="theirID1">
<span class="myclass2">My GM</span> text 1.
</span>
Then, you could:
- Have
wrapImportantWords
return true
-- which tells waitForKeyElements
that the node was not found after all, so it keeps checking.
- Have that function also check to see if the appropriate
span.myclass2
is (still) present.
Like so:
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;
}
Detecting vanished elements in general using the new MutationObserver:
In your specific case, this seems to be overkill. But, here's a method for general reference.
Notes:
- If you want to detect that a node is deleted, you have to set up the observer on its parent. Mutuation records don't seem to be available for when a node itself is deleted or completely rewritten.
In this case, we want to know when span.myclass2
s are deleted so we observe their parents (span.myclass
).
- The Mutation Summary library allegedly makes this easier.
Here is a complete Firefox Greasemonkey script. You can test it against this page. (Note that the Chrome code is the same except for the usual changes due to the lack of @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);
}
}
} );
}