3

I have a custom onclick handler for a block element (set up through jQuery's .click() method). This block element can contain links.

I'm fairly certain this is possible, so, how do I have the handler simply return if it was a link I clicked on (so that the link is visited without running my code)?

Ryan McCue
  • 1,628
  • 14
  • 23

4 Answers4

7

Check the event object to see if the target is an anchor tag then return true:

$("div").click(function(eventObject){

    if($(eventObject.target).is("a"))
        return true;

    //run your code
});
Jataro
  • 2,548
  • 1
  • 17
  • 17
  • Because the click target may also be a child (or descendant) of a link, it's safer to call ```.closest("a").length == 0``` rather than ```is("a")``` – gmcnaughton Feb 04 '13 at 20:03
2

inside your click event, you can check what the event target tagname is:

$("#myDiv").click(function(e) {
  if (e.target.tagName.toLowerCase() == "a") {
    return true; //link clicked
  } else {
    //run your usual div click code here...
  }
});
peirix
  • 36,512
  • 23
  • 96
  • 126
0

how about testing if the element is an anchor or not inside the on click function?

if(this.tagName() == "a")return true;

I didn't test it, check it and reply please

Khodor
  • 996
  • 1
  • 6
  • 13
0

Checking the nodeName of event.target doesn't work if your links have descendent elements (e.g. <span> or <img>).

Instead, try walking up the tree from event.target (the deepest element) to event.currentTarget (the event the event handler was registered on) and checking whether any of those elements are clickable:

$("div").click(function(event) {
    if (clickableBetweenTargetAndCurrentTarget(event))
        return; // This click was probably already handled.
    doSomething();
});

function clickableBetweenTargetAndCurrentTarget(event) {
    for (var el = event.target; el && el != event.currentTarget; el = el.parentNode) {
        if (isClickable(el))
            return true;
    }
    return false;
}

function isClickable(el) {
    // TODO: Customize this as appropriate for your webpage.
    return el.nodeName == 'A' || el.nodeName == 'BUTTON';
}

Demo: http://jsbin.com/fojaco/2/

Note that you'll have to customize isClickable for your particular webpage; it's hard/impossible to tell whether an element is clickable in the general case.

An alternative approach would be to make sure that all clickable descendants call event.preventDefault(), then your click listener on the div only needs to check event.defaultPrevented (IE9+). Or the descendants could call event.stopPropagation(), as suggested on another answer, but calling stopPropagation can lead to subtle bugs.

Community
  • 1
  • 1
John Mellor
  • 12,572
  • 4
  • 46
  • 35