Home › Forums › JavaScript › Event delegation and "sliding door" links?
- This topic is empty.
-
AuthorPosts
-
August 7, 2009 at 7:29 pm #25681
jlizarraga
MemberHi all,
Long time reader (of the main site), first time poster! Trying to find a cleaner way around the following issue.
Suppose I have the following markup:
Using a JS library like jQuery (I use YUI2/3 mostly but feel free to leave any responses in jQuery/mootools/etc. syntax!), I want to attach a single event listener to #demo and take advantage of event bubbling/delegation.
The event handler inspects ids to figure out what was clicked on. This means that if you click on an EM element within the link, the event handler will never know that one of the sliding door links was clicked.
Can anyone recommend a clean solution to this issue that preserves the single event handler/event delegation?
The half-solution I have come up with in my code is to create a faux-event object using the parentNode when an EM is encountered, which works fine but seems a bit too hacky. Here is an example of that (YUI3 event utility syntax here):
Code:var clickHandler = function(e){
switch(e.target.get(‘id’)){
case ‘sd1’:
alert(‘sd1 clicked.’);
break;
case ‘sd2’:
alert(‘sd2 clicked.’);
break;
default:
switch(e.target.get(‘nodeName’)){
case ‘EM’:
var oE = {
target: e.target.get(‘parentNode’),
};
that.clickHandler(oE);
break;
default:
return true;
}
}
}; // clickHandler()Thanks for any responses!
August 17, 2009 at 6:00 pm #62344akeenlabs
ParticipantI have an idea using jQuery (I don’t really know any other libraries). In the event handler, try using target.parents(‘#demo a’) to get the correct anchor if a nested element was clicked; this should work for any dom element and with an arbitrarily deep nesting. Take a look at the test page I was using:
Code:August 19, 2009 at 3:26 pm #62428jlizarraga
MemberYeah that is more or less what I am doing – checking the parent node if an EM or IMG (which are the only elements that may be within my A elements) is encountered.
I am looking for a cleaner/more elegant way to do this, but have been unable to find one for weeks (I guess this might actually be the best way).
August 20, 2009 at 11:46 am #62463akeenlabs
ParticipantSorry, I thought you were trying to clean up your existing method for the purpose of making it less "hard coded" so you could be more flexible with the code inside the anchor.
It seems like you ultimately want to stop events past the anchor tags; nothing nested within the anchor would register events so that only the anchor would register the event. It’s an interesting thought, but it’s not currently possible that I know of.
Why do you need to maintain a single event handler? Why not attach an identical handler to each ‘#demo a’ element? This isn’t hacky at all and really seems to make more sense. I’m sure you have a reason, I’m just curious as to what it is :D
August 20, 2009 at 7:42 pm #62488jlizarraga
MemberThe reason to use one event listener instead of several (AKA Event Delegation) is to save the user’s memory. One event listener uses a lot less resources than many, and since this is an AJAX app where content is added/removed a lot, it helps eliminate the risk of memory leaks associated with attaching a bunch of event listeners to A elements that might be removed/reintroduced into the document many times (not to mention a lot less code being written/executed).
I have come up with a slightly cleaner method. Instead of using a whitelist of elements for whom the parent should be checked, I give any elements whose parent should be checked when they are the event target a special class like "check-parent".
August 20, 2009 at 9:22 pm #62493Mr KiTT3N
MemberQuote:The event handler inspects ids to figure out what was clicked on. This means that if you click on an EM element within the link, the event handler will never know that one of the sliding door links was clicked.Ok i just focused on the quote above… But i know jquery has a .data() function and it can be used like so
Code:$(‘#demo’).find(‘a’).click(function(){
var $this = $(this),
data = $this.data(‘clicked’);if(data) $this.data(‘clicked’, false);
else $this.data(‘clicked’, true);console.log($this.data(‘clicked’));
return false;});
Im not sure on the requirement on using $("#demo") as the selector but that is doing the same thing as (‘#demo a’)
The html was the same but just cleared out the id’s on the anchors
Note: only time the <em> being clicked on becomes an issue is if you attach a click handler event on it then you just need to go to "$(this).parent(‘a’).data(……" this being the <em>
-
AuthorPosts
- The forum ‘JavaScript’ is closed to new topics and replies.