views:

67

answers:

6

I have a nested div like this

<div id="one">
    <div id="two">
        id two goes here
    </div>
    <div id="three">
           id three goes here
    </div>
    <div id="four">
          id four goes here
    </div>
</div>

Now i want to handle click and doubleclick events on all divs except in div#four, like this

$('#one').live('dblclick', function() {
                    my javascript code goes here
                });
('#one').live('click', function() {
                    my javascript code goes here
                });

How can i use the above script and exclude the last nested div #four.

Thanks

+6  A: 

Like this:

$('#one, #one > div').not('#four').delegate('dblclick, click', function(){
  // my javascript code goes here
});
He's using id's, not classes.
Stefan Kendall
Nice. Fast edit :).
Stefan Kendall
Using `.not()` in this matter doesn't do anything. You still only have the `#one` element, and no others. Also, this is not how you use `.delegate()`.
patrick dw
Selecting both the children and the parent should do the trick.
Stefan Kendall
Yes guys wrote it a bit quickly forgetting to fix that, thanks to @Stefan Kendall for editing/fixing it :)
@Stefan - Yes, your correction would work, but `.delegate()` is still wrong. Also, it assumes that the same code will run for `click` and for `doubleclick`.
patrick dw
@patrick: You are right but this comment of user made me write that way: Now i want to handle click and doubleclick events on all divs except in div#four
@Asif - I don't understand what you mean. I can't see how this code will work. Maybe one of the 6 users that up-voted it can explain.
patrick dw
Still i dont get a working solution, to make it more clear. .The selector i am looking for is some thing like "all div's in #one which are not of #two". This will include the #one it self. then next time i want to add an other div, i can easy add the event or exclude otherwise.
tsegay
@tsegay - Do you want to exclude the `#two` element? Your question says `#four`. Will it always be `#four`? Or will it always be the last element?
patrick dw
I dont mean only the last element, any element,not even necessary #two #four.I want to assign an event to the parent element #one and exclude any other child element, if i want to, at the same time. my code above is just a sample.
tsegay
@tsegay - I see. Do you *need* to use `.live()`? It would be easier if not. Is `#one` on the page when it first loads?
patrick dw
Yes, #one is on the DOM loaded all the time, that is my problem. And i tried .live(); both without any luck. See my code for the .live.
tsegay
@tsegay - Ok, I'll update my answer below. Let's continue the conversation there. I think I understand what you need now.
patrick dw
A: 

You must use $('#one') instead $('.one') aren't you?

Desigens
Sure, i have corrected that.
tsegay
+1  A: 

I would use an additional class:

HTML:

<div id="one">
    <div id="two" class="clickable">
        id two goes here
    </div>
    <div id="three" class="clickable">
           id three goes here
    </div>
    <div id="four">
          id four goes here
    </div>
</div>

JS:

('.clickable').live('click', function() {

});
gustavogb
Good Idea, I am looking for a kind of select all expect some, i want it to be generic. so that i don't need to add the class for any div i add to the #one.
tsegay
+3  A: 

EDIT: Based on further clarification, try this:

$('#one').bind('click dblclick', function( event ) {
    var id = event.target.id;
    if(id == "one" || id == "two" || id == "three") {
        if(event.type == "click") {
            // code for click event
        } else {
            // code for double click event
        }
    }
});​

EDIT: Based on our conversation under another answer, it seems like you want the #one element to be clickable, but none of its child elements. If that is right, try this:

$('#one').click(function() {
    // code to run when `one` is clicked.
}).children().click(function( event ) {
    event.stopPropagation();
});

Now if there's any text in #one, the code for that element will fire, but it will not fire when you click any children of #one.

Let me know if that was what you wanted.


EDIT:

If you are saying that you will have a dynamic number of elements inside #one, and the last one will not get the event, then do this:

$('#one').delegate('div:not(:last-child)', 'click dblclick', function( event ) {
    if(event.type == 'click') {
        // do something for the click event
    } else {
        // do something for the double click event
    }
});​

Note that this assumes there will not be nested divs. Results may be unexpected if there are. Also, the #one element doesn't fire events. Only its children.


Original answer:

$('#one,#two,#three').bind('click', function(){
  // code for click event
})
.bind('dblclick', function() {
   // code for double click event 
});

Or replace .bind with .live if you really need it.

patrick dw
You are almost there, but in this case, i want to be more selective in the child elements. For example from my code above i want to extend the click event to #two and #three but not to #four. and i am not sure how many child div i will have at a time. So when every time i add a div, i want to be able select if the event will be extended to that div.thanks
tsegay
@tsegay - OK, that's what I thought, but from your other comments, it sounded different. So will `#four` *always* be the element that does not get the click? Or will it change?
patrick dw
#four will be there always, but i can add more divs and i dont want to extend the event on them too.
tsegay
@tsegay - You don't want to extend the event to `#four` or to any other elements that you may add. In that case, try my update at the top of the answer.
patrick dw
Thanks, for the ur patience. Problem solved.
tsegay
@tsegay - You're welcome. Glad you got it working. :o)
patrick dw
A: 
$("div:not(#four)")

or

$("#one :not(#four)")

Will select any div that does not have the id="four" set. Basically the :not is what you are looking for. Anything in the :not parenthesis is negated for selection purposes.

http://api.jquery.com/not-selector/

An alternative is to attach a single click/double click handler to the parent which means no need for .live or anything, and in the handler ensure that you are receiving a click from an acceptable child with $(event.target).is(":not(#id)")

$("#one").click(function(event) {
    if (this != event.target && $(event.target).is(':not(#four)')) {
       // do work on event.target
    }
});
// ...
Dmitriy Likhten
The selector i am looking for is some thing like "all div's in #one which are not of #two". This will include the #one it self. then next time i want to add an other div, i can easy add the event or exclude otherwise.
tsegay