Brett Brett - 6 months ago 39
jQuery Question

Binding an onclick event to an anchor tag with children and getting attrubute data from the anchor

I have a situation where I have attached an

onclick
event to an anchor tag, but it has a
span
tag inside as a child; hence when I do something like this:

HTML:

<a href="#" class="toggle js-toggle" data-target-cat="3">
<span class="icon-angle-down"></span>
</a>


JS:

$('.js-toggle').on('click', function(e) {

e.preventDefault();

var cat_id = $(e.target).data('target-cat');

});


It doesn't work as
e
represents the
span
element; sure I can just put the attribute on the span again, but I am paranoid that sometimes the
anchor
may trigger it rather than the
span
and I don't want to duplicate the attribute on both elements.

So I decided to do this:

$('.js-toggle').on('click', function(e) {

e.preventDefault();

var cat_id = $(e.target).data('target-cat');

if (typeof cat_id === "undefined") {
// Seems the click was triggered by a child of the anchor tag; grab it from the parent
cat_id = $(e.target).parent().data('target-cat');
}

});


This works, however I'm not overly comfortable doing it this way as what happens if the children elements change inside the anchor.

Is there a more consistent way of doing this or should I perhaps put the
onclick
event on the
span
tag instead?

Bonus Question: Why does
e.preventDefault();
work if
e
represents the
span
tag and not the
anchor
?

Answer

You're using event.target which references the element the event was initiated for. But what you want is to access the element you registered the event handler on - see event.currentTarget.

For your "bonus question" you need to understand that the default action can be prevented on any element at anytime during the capture or bubble phase. That said, because you registered the event handler on the <a>, that's where you're preventing the default, not on the the <span> as you assumed.

Comments