Running code whenever an AJAX page changes
From Chickenfoot Script Repository
Trigger scripts that trigger on a page load aren't as useful on AJAX web sites where the URL never changes. The trigger script runs when you first visit the site, but never thereafter. Here's a useful function that allows you to run some code every time the page's contents are changed. This will eventually be integrated into Chickenfoot as a built-in command.
function whenChanged(/*Function*/ handler) {
var aboutToCallHandler = false;
var docs = Chickenfoot.getAllFrameDocuments(document);
for (var i = 0; i < docs.length; ++i) {
var doc = docs[i];
doc.addEventListener("DOMNodeInserted", changed, false);
doc.addEventListener("DOMNodeRemoved", changed, false);
doc.addEventListener("DOMAttrModified", changed, false);
}
// TODO: when new iframes appear, we need to attach listeners to
// them too
function changed() {
if (!aboutToCallHandler) {
aboutToCallHandler = true;
setTimeout(callHandler, 1);
}
}
function callHandler() {
try {
handler();
} finally {
aboutToCallHandler = false;
}
}
}
Here's an example of a script that uses whenChanged. It modifies the page so that clicking on any link opens the link in a new tab, rather than the current tab. By using whenChanged(), it ensures that any new links added to the page (by AJAX or Javascript) are modified the same way. I use this on my iGoogle home page.
// ==UserScript==
// @name iGoogle
// @when Pages Match
// @description Makes links open in a new tab.
// @includes http://www.google.com/ig
// ==/UserScript==
openLinksInNewTab()
whenChanged(function() {
openLinksInNewTab()
});
function openLinksInNewTab() {
for (var link in find("link")) link.element.target = "_new";
}
function whenChanged(/*Function*/ handler) {
var aboutToCallHandler = false;
var docs = Chickenfoot.getAllFrameDocuments(document);
for (var i = 0; i < docs.length; ++i) {
var doc = docs[i];
doc.addEventListener("DOMNodeInserted", changed, false);
doc.addEventListener("DOMNodeRemoved", changed, false);
doc.addEventListener("DOMAttrModified", changed, false);
}
// TODO: when new iframes appear, we need to attach listeners to
// them too
function changed() {
if (!aboutToCallHandler) {
aboutToCallHandler = true;
setTimeout(callHandler, 1);
}
}
function callHandler() {
try {
handler();
} finally {
aboutToCallHandler = false;
}
}
}
