Reputation: 4160
Im using event handlers from a framework (prototype to be specific) to attach listerners to certain elements of a page like this:
//html
<a href="?default=1" class="default">Set Default</a>
//js
document.observe('dom:loaded', function(){
//get all elements with d 'default' classname
for(i = 0;i < document.getElementsByClassName('default').length;i++)
{
s = document.getElementsByClassName('default')[i];
//attach an onclick event
s.observe('click', function(e){
//prevent the default action (i.e loading the page)
e.preventDefault();
//read d link attribute
ref = this.readAttribute('href');
//and now, do it the ajax way
new Ajax.Request('js/ajax/handler.php'+ref, {
method:'get',
onSuccess:function(transport){}
});
});
}
});
It works well. Really well. But there is a challenge. Most times, such actions manipulates the DOM and may add one or more of the 'default' class element (i.e another Set Default somewhere). That is intentional actually. But then, the newly added 'default' class element will not have the click event attached. The shitty work around at the moment is to loop through all the 'default' classes again and re-attach the events. Any other ideas?
Upvotes: 1
Views: 633
Reputation: 1074108
The usual way to solve that is via event delegation. If you hook the click
event on a container that holds all of these .default
items, you can respond in that one handler:
document.observe('click', function(event) {
var elm;
elm = event.findElement('.default');
if (elm) {
// do your nifty stuff with the element
}
});
It doesn't have to be document
if they share some higher-up container. Docs for Event#findElement
are here.
BTW, there's a big performance problem with your for loop. You're calling document.getElementsByClassName
on every iteration! If you use event delegation, that loop goes away anyway, but if that doesn't work for whatever reason, call it once and then loop through the result:
var defaults = document.getElementsByClassName('default');
for (i = 0; i < defaults.length; i++)
Upvotes: 2
Reputation: 87420
You could listen to all click events on the page, then use the event's target to determine if the user clicked on an element with the className "default".
Upvotes: 1