views:

137

answers:

5

I want to attach a "mouseup" event on all nodes of a container, including text nodes using jQuery. How do I do that?

Update:

If I had some HTML fragment like this:

<p>Some text node <strong>strong text</strong> another text node.</p>

Currently, $("p *") will apply the event to the <p> and <strong> but not to the 2 textnodes within <p> separately. Modifying the source to add classes is not an option.

A: 

I think the easiest would be to add a class to all your nodes. The jquery selector will be as simple as : $('.yourClassName').dostuff()

Rodolphe
+1  A: 
$('#container *').mouseup(function() { ... });

That will bind the mouseup event handler to all nodes inside #container.

EDIT

Changed click -> mouseup to be clearer.

Tatu Ulmanen
+2  A: 

While Tatu's answer ought to work (except use .mouseup instead of .click), are you sure you actually need an event handler on every single node? If you bind using

$('#container').mouseup(function(event){//code})

the event bubbling model will call that same func anytime the mouseup event occurs on any element inside #container, and the DOM node that actually triggered the event will be contained in the event.target property. This is much more efficient in most cases.

nezroy
Please see my the update to my question. When I do a alert(this) from the event handler, I want the node to be the textnode and not the parent <p> node.
jeffreyveon
I don't know if jQuery can select text nodes currently. There was a discussion on it here: http://www.mail-archive.com/[email protected]/msg14384.htmlAnd an old prototype plugin for doing it here: http://dev.jquery.com/browser/trunk/plugins/textNodes?rev=2052
nezroy
@jefferyveon, you can get the actual node called using this technique. It's not jQuery, but here's a tutorial from sitepoint.com: http://www.sitepoint.com/blogs/2008/07/23/javascript-event-delegation-is-easier-than-you-think/#
Robert Gowland
A: 

You cannot set event handlers on a Text node. Text nodes do not implement the EventTarget interface like Element nodes, the Document node and the window object do.

You should never need to, either. Set one mouseup handler on the parent element and you will get mouseup events for all its child content. This is because the mouseup event ‘bubbles’ up through its ancestors.

bobince
Ok, then how do I get a reference to the textnode that I click upon?
jeffreyveon
Sorry, you can't — not in any cross-browser way, anyhow; event originate only on EventTargets. Mozilla does give you `event.explicitOriginalTarget` that can point to a Text node but there's nothing on the other browsers. If you need to distinguish clicks in the text you'll need to wrap with elements (see rosscj's answer).
bobince
+2  A: 

bobince is right that you cannot set event handlers on a Text node. It sounds like you want something like

<p><span>Some text node</span> <strong>strong text</strong><span> another text node.</span></p>

and the events would get attached to the span tags. However that wouldn't work if you can't change the source.

rosscj2533
You could perhaps wrap the text nodes in tags from script, eg. something like `$.each(p.childNodes, function() { if (this.nodeType==3) $(this).wrap('<span></span>'); };`
bobince