2

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?

3 Answers3

7

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.

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 3
    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 Jul 18 '09 at 07:41
  • 1
    @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 Jul 18 '09 at 14:58
6

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
  • 78,161
  • 20
  • 151
  • 159
  • 2
    Event delegation is baked right into jQuery with live() -> http://docs.jquery.com/Events/live – James Jul 18 '09 at 10:02
  • yeah but it has its own overheads. – redsquare Jul 18 '09 at 14:07
  • 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 Jul 18 '09 at 15:52
1

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.

Walter Rumsby
  • 7,435
  • 5
  • 41
  • 36