Event Bubbling vs Event Capture
Small example showing the differences between event bubbling and event capture.
by Couto
HTML
<link rel="stylesheet" href="https://rawgithub.com/necolas/normalize.css/master/normalize.css">
<link rel="stylesheet" href="http://topcoat.io/topcoat/css/topcoat-desktop-dark.css">
<div class="example"> First Element
<div class="example"> Second Element
<div class="example"> Third Element </div>
</div>
</div>
<button class="topcoat-button--cta">Currently using Bubbling</button>
<button class="topcoat-button">Reset Counters</button>
CSS
.example {
padding: 15px; margin: 15px;
font: 12px 1.5 "Helvetica Neue", Helvetica, Arial;
font-weight: bold;
border: 1px solid #bbb;
color: #444;
background-color: white;
position: relative;
cursor: pointer;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-font-smoothing: antialiased;
}
button {
margin: 0 25px;
}
.example:hover {
background-color: #efefef;
cursor: pointer;
}
.example:active {
background-color: #ccc;
border: 1px solid #999;
cursor: pointer;
}
.badge {
position: absolute;
bottom: 7px;
right: 7px;
}
JavaScript
(function(d) {
var divs = d.querySelectorAll('div'),
button = d.querySelectorAll('button'),
counter = 1,
capture = false,
callback = function(evt) {
var el = evt.currentTarget,
badge = d.createElement('span');
badge.setAttribute('class', 'badge badge-inverse');
badge.innerHTML = counter;
el.appendChild(badge);
counter += 1;
},
removeBadges = function() {
var badges = d.querySelectorAll('.badge'),
i = badges.length - 1;
while (i >= 0) {
badges[i].parentNode.removeChild(badges[i]);
i -= 1;
}
counter = 1;
},
removeListeners = function() {
var i = divs.length - 1;
while (i >= 0) {
divs[i].removeEventListener('click', callback, capture);
i -= 1;
}
},
addListeners = function() {
var i = divs.length - 1;
while (i >= 0) {
divs[i].addEventListener('click', callback, capture);
i -= 1;
}
};
addListeners();
button[0].addEventListener('click', function(evt) {
removeBadges();
removeListeners();
capture = !capture;
addListeners();
if (capture) {
this.innerHTML = 'Currently using Capture';
} else {
this.innerHTML = 'Currently using Bubbling';
}
});
button[1].addEventListener('click', removeBadges);
}(document));