I have a Greasemonkey script which uses jQuery and detects if a "class" is present in the document.
var damageMessage = $(".mw_error").text();
Thanks to ShankarSangoli he or she gave me the solution to finding the class when the iframe loads with.
$("iframe").load(function(){
var damageMessage = $(this).contents().find(".mw_error").text();
});
The problem I have now is that some of the links in the iframe load content via ajax so the iframe doesn't refresh and I cant get the new value for the class "mw_error". It was suggested that I use a ajax success callback but I'm unsure how to do this.
Any help on this would be much appreciated :)
You can listen for ajax calls, but that gets overly complicated, depending on the target pages. The most robust way to get ajax-ified content on a wild page is to poll for it, like so:
function myCode (jNode) {
//YOUR CODE HERE
var damageMessage = jNode.text();
//...
}
waitForKeyElements (".mw_error", myCode, false, "iframe");
function waitForKeyElements (
selectorTxt, /* Required: The jQuery selector string that
specifies the desired element(s).
*/
actionFunction, /* Required: The code to run when elements are
found. It is passed a jNode to the matched
element.
*/
bWaitOnce, /* Optional: If false, will continue to scan for
new elements even after the first match is
found.
*/
iframeSelector /* Optional: If set, identifies the iframe to
search.
*/
)
{
var targetNodes, btargetsFound;
if (typeof iframeSelector == "undefined")
targetNodes = $(selectorTxt);
else
targetNodes = $(iframeSelector).contents ()
.find (selectorTxt);
if (targetNodes && targetNodes.length > 0) {
/*--- Found target node(s). Go through each and act if they
are new.
*/
targetNodes.each ( function () {
var jThis = $(this);
var alreadyFound = jThis.data ('alreadyFound') || false;
if (!alreadyFound) {
//--- Call the payload function.
actionFunction (jThis);
jThis.data ('alreadyFound', true);
}
} );
btargetsFound = true;
}
else {
btargetsFound = false;
}
//--- Get the timer-control variable for this selector.
var controlObj = waitForKeyElements.controlObj || {};
var controlKey = selectorTxt.replace (/[^\w]/g, "_");
var timeControl = controlObj [controlKey];
//--- Now set or clear the timer as appropriate.
if (btargetsFound && bWaitOnce && timeControl) {
//--- The only condition where we need to clear the timer.
clearInterval (timeControl);
delete controlObj [controlKey]
}
else {
//--- Set a timer, if needed.
if ( ! timeControl) {
timeControl = setInterval ( function () {
waitForKeyElements ( selectorTxt,
actionFunction,
bWaitOnce,
iframeSelector
);
},
500
);
controlObj [controlKey] = timeControl;
}
}
waitForKeyElements.controlObj = controlObj;
}
Beware that Greasemonkey can also run on iFrames, so you may not need to do anything other than know if you're in an iFrame, depending upon the script's purpose.
Conversely, you can get unexpected results if the GM script(s) fire on the iFrame URL when you haven't planned on it.
For example, suppose you had this page at URL_A:
<body>
<iframe src="URL_B"></iframe>
</body>
And the GM script's // @include
directive(s) covered both urls (// @include URL_*
, etc.).
Then if the script just had alert ('Script start.');
, you would see 2 alerts upon loading the page.