When you double-click that image (#iconImage_3
), the target page creates an <iframe>
that contains the content you are looking for. CSS is used to make it look like a new window.
This is an AJAX scenario. That iframe does not exist when the page loads and your userscript runs. You need a way to make your script wait for that iframe. One easy, robust way to accomplish this is to use the waitForKeyElements() utility.
For example, visit this Dynamic Iframe test page on jsBin:
<!DOCTYPE html>
<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready (jQueryMain);
function jQueryMain () {
//--- If this is the iframe, change the content.
if (/BeAnIframe/i.test (location.search) ) {
$("body").html (
'<h4>This is iFrame content</h4>' +
'<button id="generateMessageBtn">This is the button to click via userscript.</button>'
);
$("button").click ( function () {
$("body").append ('<p>Button was clicked.</p>');
} );
}
else {
$("button").click ( function () {
$("body").append (
'<div><iframe src="' + location.href + '?BeAnIframe=1"></iframe></div>'
);
} );
}
}
</script>
</head><body>
<p>Click the button below, and then the userscript will click the button that appears in the iframe.</p>
<p><button>Open the iframe below.</button></p>
</body></html>
It looks like this:

Then, when you click the button, it looks like this:

The iframe and contents were added via AJAX.
A simple Tampermonkey, or Greasemonkey, script to click that iframed button is:
// ==UserScript==
// @name Dynamic iframe content clicker
// @include http://jsbin.com/xuwosovi/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/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.
*/
if (window.top == window.self) {
//-- Only runs if it's not an iframe.
waitForKeyElements (
"#generateMessageBtn",
clickMessageButton,
false,
"iframe[src*='BeAnIframe']"
);
}
function clickMessageButton (jNode) {
var clickEvent = document.createEvent ('MouseEvents');
clickEvent.initEvent ('click', true, true);
jNode[0].dispatchEvent (clickEvent);
}
Note that:
#generateMessageBtn
is the jQuery selector for the iframed button.
iframe[src*='BeAnIframe']
is a jQuery selector for the iframe itself, keying off the src
attribute which is important for your particular situation.
Go ahead and install that script and then visit the test page. When you click the first button, You'll see a message indicating that the second button was clicked by the userscript.
Now, for your specific scenario, A script like this should click the indicated node. (We can't test it.)
// ==UserScript==
// @name Dynamic iframe content clicker
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/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.
*/
if (window.top == window.self) {
//-- Only runs if it's not an iframe.
waitForKeyElements (
"#messageHeader_6328087",
processMessageWindow,
false,
"iframe[src*='messagesBox.aspx?view=inbox']"
);
}
function processMessageWindow (jNode) {
var clickEvent = document.createEvent ('MouseEvents');
clickEvent.initEvent ('click', true, true);
jNode[0].dispatchEvent (clickEvent);
}
If that works, this question is answered. Open a new question for additional problems, but you should be able to populate your variables r
and s
by modifying processMessageWindow()
like so:
function processMessageWindow (jNode) {
var clickEvent = document.createEvent ('MouseEvents');
clickEvent.initEvent ('click', true, true);
jNode[0].dispatchEvent (clickEvent);
var frameBody = jNode.parents ("body");
var r = frameBody.find (".even.unread").get ();
var s = frameBody.find (".odd.unread").get ();
// Add additional processing here...
}
Note:
.parents()
, .find()
and .get()
are jQuery functions.
- You can't use
document.getElementsByClassName
for this. document
still points to the parent window, not the iframe.