views:

124

answers:

3

If I have a button:

<button id="button1">

Normally I would write:

$("#button1").click(function ()
{    
    //do something
}

But I want to define a function that responds to all click events except when someone clicks on this button.

Is there a selector that would allow me to target all other clickable elements in the document except button1?

+6  A: 

You could use the :not selector:

$('button:not(#button1)').click(function(){
  //Do something
});

The above selector will match all the button elements, except the one with id = "button1".

If you want really to select all the elements under the body tag, you can use the "All" (*) selector, and also exclude the elements with :not(selector) or .not(expr):

$('body *:not(#button1)').click(function(){
  //Do something
});

Or

$('body *').not('#button1').click(function(){
  //Do something
});

If you do so, you could have some event bubbling or propagation issues, you can handle this with the event.stopPropagation function.

CMS
Great answer. Thanks.
fritz carlton
You're welcome!
CMS
Not a good solution. You could end up attaching 100's of click events. Event Delegation would be best here where you check the event.target
redsquare
@redsquare - In the case of the body selector maybe. But in the case of 'button:not(#button1)', you only add as many click events as you have buttons. I think I understand your concern though.
fritz carlton
+1  A: 

The current CSS 3 Selectors Candidate Recommendation defines the :root pseuedo class.

The :root pseudo-class represents an element that is the root of the document. In HTML 4, this is always the HTML element.

You could attach an event listener to the root and then check which element received the click. If it's the element you want to ignore return, otherwise do whatever it is you want to do.

wrumsby
Sounds browser dependent if it's a candidate spec.
fritz carlton
The selector engines provided by JavaScript libraries like jQuery implement CSS 3 Selectors, e.g. you can use selectors in jQuery that aren't implemented by the browser quite happily.
wrumsby
Thanks for clarifying. I didn't realize that's how it worked.
fritz carlton
+6  A: 

I know you have accepted the answer above but I would advise strongly against this. You can use event delegation to do what you want with a lot less overhead to the dom.

I know .live() exists but too many live handlers also impact performance. I prefer event delegation old style.

Demo here

$(function(){
    $('body').click( clickFn );
  });

  function clickFn( ev ) {

    if (ev.target.id != 'button1' ){
       //do your stuff
       console.log('not a #button1 click');
    }

  }
redsquare
Event delegation is baked right into jQuery with live() -> http://docs.jquery.com/Events/live
J-P
yeah but it has its own overheads.
redsquare
Thanks. I have started trying to implement your solution in my code but I'm confused about the syntax you used. I have added a new question to try to clarify my confusion: http://stackoverflow.com/questions/1147864/correct-syntax-for-defining-an-event-delegator
fritz carlton