Using jQuery To Bind And Trigger Event Handlers On Detached DOM Nodes

Posted August 27, 2010 at 5:00 PM by Ben Nadel

Tags: Javascript / DHTML

Often times, we use jQuery to bind event handlers to DOM nodes that are children of the current document tree. When we do this, jQuery stores the event handlers in the given node's "events" collection. These bindings remain in place until they are explicitly unbound or until the DOM nodes are removed from the document (NOTE: Using .detach() does not unbind event handlers). Because of this fact, I think it is tempting to believe that detached DOM nodes can't react to events; but, in fact, the opposite is true - jQuery can both bind and triggered events on nodes that are not part of the currently rendered document.

To demonstrate this, I am going to create a free-standing DOM node within my Javascript. Then, I am going to bind a custom event handler to it and trigger the bound event programmatically.

  • <!DOCTYPE html>
  • <html>
  • <head>
  • <title>jQuery Eventing Binding On Detached DOM Nodes</title>
  • <script type="text/javascript" src="./jquery-1.4.2.js"></script>
  • <script type="text/javascript">
  •  
  • // Create a DOM node; note that this DOM node will not be
  • // part of any DOM tree - it is free standing.
  • var freeNode = $( "<div />" );
  •  
  • // Bind a custom event to the free-standing node. We are
  • // attaching additional information to this event binding
  • // to test the various aspects of event binding.
  • freeNode.bind(
  • "ping",
  • {
  • isAttached: false
  • },
  • function( event, timeLine ){
  • console.log( "Triggered: ", arguments );
  • }
  • );
  •  
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  •  
  • // Before we try to use the event bindings, let's see if
  • // we can see the attached event handlers.
  • console.log( freeNode.data( "events" ) );
  •  
  • // Now that we have our bound event, let's try to trigger
  • // the custom event on our free-floating DOM node.
  • freeNode.trigger( "ping", [ "preRemove" ] );
  •  
  • // Now, just for a sanity check, let's attach it to the DOM
  • // tree and then remove it -- the expected behavior is that
  • // the event binding will be removed.
  • freeNode
  • .appendTo( "body" )
  • .remove()
  • ;
  •  
  • // Now, let's try to trigger the event on the removed node.
  • freeNode.trigger( "ping", [ "postRemove" ] );
  •  
  • // As a final test, just log the current event bindings.
  • console.log( freeNode.data( "events" ) );
  •  
  • </script>
  • </head>
  • <body>
  • <!-- Intentionally left blank. -->
  • </body>
  • </html>

As you can see, we are creating a detached DIV node. Then, we are binding the custom event, "ping," to that node with some bind-time data. Once the event handler is bound, I am then using jQuery to programmatically trigger the event, all while it is detached from the document.

As a sort of control-case, I am also attaching and removing the node to and from the Body element in order to confirm that remove() still clears all bound data (including the "events" collection). When I run the above code, I get the following console output:

 
 
 
 
 
 
jQuery Can Both Bind And Trigger Events On Detached DOM Nodes. 
 
 
 

As you can see, both the event binding and the event triggering executed successfully while our DIV remained detached from the current document tree. And, just as we have seen previously, attaching and then detaching the DIV resulted in a loss of event binding.

It might seem odd to care about event binding outside the context of the current document tree; but, I have some ideas that I want to play with that leverage this very behavior. More to come on that later.




Reader Comments

Aug 27, 2010 at 11:08 PM // reply »
13 Comments

very cool, i knew this was normal, but never really thought of using it for something useful, you got me thinking tho! look forward to seeing what you come up with!


Aug 28, 2010 at 4:27 AM // reply »
2 Comments

You have me a little curious as to what benefits having an element not attached to the DOM will bring too.


Aug 28, 2010 at 1:30 PM // reply »
69 Comments

My guess is, you're going to create a div and attach web socket or web worker events to it, so that the div itself can interactively build its own contents, prior to attaching itself to the DOM to display its contents.

I'll bet that kind of encapsulation appeals to you. :-)


Aug 30, 2010 at 10:12 AM // reply »
10,638 Comments

@Steve,

Interesting idea with the WebSockets.

@All,

Here's where I was going with that - using jQuery's native event architecture to power publication/subscribe (pub/sub) functionality within a Javascript application's domain model:

http://www.bennadel.com/blog/2000-Powering-Publish-And-Subscribe-Functionality-With-Native-jQuery-Event-Management.htm


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 3, 2012 at 10:49 PM
How I Got Node.js Running On A Linux Micro Instance Using Amazon EC2
Wow this was really helpful! Only thing I would add is you need to update your .bash_profile after you edit the secure_path. This is what I did: $ . ~/.bash_profile Otherwise, NPM won't be found. ... read »
Feb 3, 2012 at 10:14 PM
Pushing Base64-Encoded Images Over HTML5 WebSockets With Pusher And ColdFusion
@Ben, Just wanted to let you know that pusher are soon to start limiting sizes on messages. This was the detail that came through in the Feb dispatch: "However, we will soon be limiting the s ... read »
Feb 3, 2012 at 5:05 PM
Regular Expressions Make CSV Parsing In ColdFusion So Much Easier (And Faster)
I tried using your RegEx in my C# program, but it was matching an extra empty-string at the end and so I would end up with an extra field that doesn't exist, so I changed it to this: (^|,)("(?: ... read »
Feb 3, 2012 at 3:47 PM
ColdFusion Supports HTTP Verbs PUT And DELETE (As Well As GET And POST)
Josh Cyr posted this on Twitter just a little bit ago. Thought it was appropriate. http://stackoverflow.com/questions/1619152/how-to-create-rest-urls-without-verbs/1619677#1619677 ... read »
Feb 3, 2012 at 2:28 PM
Changing The Execution Context Of Your Self-Executing Function Blocks In JavaScript
@Michael, You definitely make a good point (and extra points for quoting movies - I love movies). When you use a return() statement to define the object's public API, it does provide a consistent a ... read »
Feb 3, 2012 at 2:04 PM
Changing The Execution Context Of Your Self-Executing Function Blocks In JavaScript
To quote Jurassic Park: "Just because you can doesn't mean you should". I completely, utterly disagree with the thought that this is more readable. Consider the current module pattern: if ... read »
Feb 3, 2012 at 1:10 PM
REST API Design Rulebook By Mark Masse
@Jordan, Yeah, WRML was created by Mark Masse (author of the book). I also found it to be a bit convoluted. I suppose it is intended to allow the Client to be able to programmaticaly respond to cha ... read »
Feb 3, 2012 at 1:08 PM
ColdFusion Supports HTTP Verbs PUT And DELETE (As Well As GET And POST)
@Jason, To be honest, I don't have good answers for that kinds of stuff. And, to the point, that is specifically why I *really* liked the REST API Design Rulebook by Mark Masse - he just cuts throu ... read »