Category:Ajax site tips: Difference between revisions
Added "Listen for DOMNodeInserted event" |
Extended article with the stuff I learned the past two days. Hopefully, this helps a few people. |
||
Line 4: | Line 4: | ||
== Catch bubbling events == | == Catch bubbling events == | ||
To react on changements of the document, e.g appearing nodes, you can add new event listeners to the document or any other node with the [http://developer.mozilla.org/en/docs/DOM:element.addEventListener element.addEventListener()] function: | |||
<code> | |||
target.addEventListener(type, listener, useCapture); | |||
</code> | |||
This is useful since elements you want to attach listeners to might not be in the [[DOM]] yet when the page/script loads. | Example: This code will tell you what element you click, unless it or some ancestor element does <code>event.stopPropagation()</code>. This is useful since elements you want to attach listeners to might not be in the [[DOM]] yet when the page/script loads. | ||
<code> | |||
document.addEventListener('click', function(event) { | |||
GM_log("Clicked " + event.target); | |||
}, true); | |||
</code> | |||
Note that the second argument has to be a function or the name of a function and not code itself. If you want code to be executed but not define an extra function, you can use an inline function like in the example above. The function is called with one parameter with an attribute <code>target</code>, which is the element that raised the event. | |||
=== Example scripts === | === Example scripts === | ||
* [http://userscripts.org/scripts/show/2419 Gmail attachment reminder] | * [http://userscripts.org/scripts/show/2419 Gmail attachment reminder] | ||
== Listen for DOMNodeInserted event == | |||
When new nodes are inserted into the DOM tree, an <code>DOMNodeInserted</code> event is raised at the inserted node and bubbles up the tree until its propagation is stopped. You can handle it with an event handler at the document node. The following code shows an alert with the id of any new node in the document. | |||
<code> | |||
document.addEventListener('DOMNodeInserted', function (event) { alert(event.target.id + ' has been added'); }, false); | |||
</code> | |||
Sometimes, new nodes appear in the document without being inserted in a way that they would raise <code>DOMNodeInserted</code> events. This happens for example when the element.innerHTML attribute is used. In this case, you can add listeners for the <code>DOMAttrModified</code> event. The following code is copied from a [http://userscripts.org/scripts/show/11003 userscript for the german StudiVZ]: | |||
<code> | |||
/* watch for any changed attributes */ | |||
document.addEventListener("DOMAttrModified", documentChanged, false); | |||
function documentChanged(event) { | |||
// alert(event.target.id); /* helpfull for debugging */ | |||
if (event.target.id == "get_kds_link" || /* if one of those nodes are modified, call ''myFunction'' */ | |||
event.target.id == "checkcode") { | |||
myFunction(); | |||
} | |||
} | |||
</code> | |||
There are other event types you might want to listen for, which are listed on the [http://www.w3.org/TR/DOM-Level-3-Events/events.html#Events-EventTypes-complete W3C website]. | |||
== | === Example scripts === | ||
This code is from Jesse Ruderman's [http://www.squarefree.com/userscripts/autolink.user.js?source Autolink] script: | This code is from Jesse Ruderman's [http://www.squarefree.com/userscripts/autolink.user.js?source Autolink] script: | ||
<code> | |||
var moddingDOM = false; | var moddingDOM = false; | ||
Line 43: | Line 77: | ||
go(e.target); | go(e.target); | ||
} | } | ||
</code> | |||
{{stub}} | {{stub}} | ||
[[Category:Site-specific tips]] | [[Category:Site-specific tips]] |
Revision as of 21:59, 19 August 2007
Ajax-driven or JavaScript-heavy sites often require different strategies than when scripting a regular site: elements appear, disappear and change at any time. This page contains some tips for scripting such sites.
Catch bubbling events
To react on changements of the document, e.g appearing nodes, you can add new event listeners to the document or any other node with the element.addEventListener() function:
target.addEventListener(type, listener, useCapture);
Example: This code will tell you what element you click, unless it or some ancestor element does event.stopPropagation()
. This is useful since elements you want to attach listeners to might not be in the DOM yet when the page/script loads.
document.addEventListener('click', function(event) {
GM_log("Clicked " + event.target);
}, true);
Note that the second argument has to be a function or the name of a function and not code itself. If you want code to be executed but not define an extra function, you can use an inline function like in the example above. The function is called with one parameter with an attribute target
, which is the element that raised the event.
Example scripts
Listen for DOMNodeInserted event
When new nodes are inserted into the DOM tree, an DOMNodeInserted
event is raised at the inserted node and bubbles up the tree until its propagation is stopped. You can handle it with an event handler at the document node. The following code shows an alert with the id of any new node in the document.
document.addEventListener('DOMNodeInserted', function (event) { alert(event.target.id + ' has been added'); }, false);
Sometimes, new nodes appear in the document without being inserted in a way that they would raise DOMNodeInserted
events. This happens for example when the element.innerHTML attribute is used. In this case, you can add listeners for the DOMAttrModified
event. The following code is copied from a userscript for the german StudiVZ:
/* watch for any changed attributes */
document.addEventListener("DOMAttrModified", documentChanged, false);
function documentChanged(event) {
// alert(event.target.id); /* helpfull for debugging */
if (event.target.id == "get_kds_link" || /* if one of those nodes are modified, call myFunction */
event.target.id == "checkcode") {
myFunction();
}
}
There are other event types you might want to listen for, which are listed on the W3C website.
Example scripts
This code is from Jesse Ruderman's Autolink script:
var moddingDOM = false;
window.addEventListener("load", init, false);
function init()
{
document.addEventListener("DOMNodeInserted", nodeInserted, false);
setTimeout(go, 50, document.body);
}
// This makes it work at Gmail.
// 20% performance penalty on a plain text file with a link on almost every line.
// Tiny performance penalty on pages with few automatically added links.
function nodeInserted(e)
{
// our own modifications should not trigger this.
// (we don't want our regular expression objects getting confused)
// (we want better control over when we recurse)
//GM_log("Inserted: " + e.target);
if (!moddingDOM)
go(e.target);
}
This category currently contains no pages or media.