Search code examples
jquerymouseclick-event

Detect background click in jQuery


Say I have the following HTML:

<div>
  <span>span text</span> div text <span>some more text</span>
</div>

I want to make it so that when I click on span, it will trigger some event (e.g. to make the text bold), that's easy:

$('span').click( ... )

But now I when I click away from the element, I want another event to trigger (e.g. to make the text normal weight). I need to detect, somehow, a click not inside the span element. This is very similar to the blur() event, but for non INPUT elements. I don't mind if this click is only detected inside the DIV element and not the entire BODY of the page, btw.

I tried to get an event to trigger in non-SPAN elements with the following:

$('div').click( ... ) // triggers in the span element
$('div').not('span').click( ... ) // still triggers in the span element
$('div').add('span').click( ... ) // triggers first from span, then div

Another solution would be to read the event's target inside the click event. Here's an example of implementing it this way:

$('div').click(function(e) {
  if (e.target.nodeName != "span")
     ...
});

I was wondering if there was a more elegant solution like blur() though.


Solution

  • Your last method should work best even if it's messy. Here's a little refinement:

    $('span').click(function() {
        var span = $(this);
        // Mark the span active somehow (you could use .data() instead)
        span.addClass('span-active');
    
        $('div').click(function(e) {
            // If the click was not inside the active span
            if(!$(e.target).hasClass('span-active')) {
                span.removeClass('span-active');
                // Remove the bind as it will be bound again on the next span click
                $('div').unbind('click');
            }
        });
    });
    

    It's not clean, but it should work. No unnecessary binds and this should be foolproof (no false positives etc).