Wednesday, 22 October 2014

Stop Clicks Bubbling Up the DOM (Event Propagation)

When a user clicks on an element it triggers the onClick event of that element, and every parent element up the DOM. This is normally fine as it's rare to have a click on an element who has an ancestor with a click event too, but on those rare occasions where there is an ancestor with a click event it can be the most annoying thing ever. The last thing you want is to prevent the user from interacting with a button because it also triggers some other interaction. This can be stopped in many ways, but thankfully there is an AngularJs way to do it.

$event.stopPropagation()

Say you've created a piece of HTML that has a couple of divs to be clicked on:

<div data-ng-click="topClick()">
    <h1>Click me!</h1>
    <div data-ng-click="bottomClick()">
        <h2>Click me too!</h2>
    </div>
</div>


With the above code, every time you click the div with the h2 and trigger bottomClick(), you're also going to trigger topClick(). This may cause your code to execute when you don't want it to, and is most likely going to lead to a really confusing experience (and an unexpected journey) for your user.

The solution here is to add $event.stopPropagation() into the ngClick along with bottomClick(), so that your code looks like:

<div data-ng-click="bottomClick(); $event.stopPropagation()">

It doesn't matter if it goes before or after the function call you want to trigger, but I think it makes more sense and is easier to read if you place it afterwards.

I've hosted this example if you want to see it in action.

Note: I've used data-ng-repeat here so that my html passes validation. You can choose whether or not to prefix ng-repeat - and what with - based on your own needs.

No comments:

Post a Comment