Delegation & bubbling
by LeGEC
HTML
<div><span id="target">Handler is bound to <code>document</code>.<br/>Click events will bubble through <code>div.clickCount</code> (even though the handler calls <code>e.stopPropagation()</code>).</span>
<br/>
<br/>Click one of the buttons to change the target :
<br/>
<button id="doc">document</button>
<button id="parent">parent</button>
</div>
<div class="clickCount">
<div class="parent">
<div class="child">button</div>
<div class="child">button</div>
</div>
<div class="parent">
<div class="child">button</div>
</div>
</div>
<div id="log"> <span id="clickCount">0</span> clicks have been registered by <code>div.clickCount</code> (red border).</div>
CSS
.clickCount {
border:1px solid red;
margin: 6px
}
.parent {
border: 1px solid black;
margin: 3px
}
.child {
width : 150px;
background: green;
margin: 6px;
text-align: center
}
JavaScript
// the click handler function :
// it calls e.stopPropagation()
// depending on the node it is bound to, the event will bubble through different layers
function handler(e) {
var $p = $('<p>Clicked</p>').appendTo('#log').delay(1000).fadeOut();
e.stopPropagation();
};
// clickCount :
// the ".clickCount" div increments a counter each time it sees a click event
var clickCount = 0;
$('.clickCount').click(function () {
clickCount++;
$('#clickCount').html(clickCount);
});
// #doc and #parent buttons :
// change the target of the ".on('click', '.child', handler)" binding
$('#doc').click(function () {
$('.parent').off('click', '.child');
$(document).off('click', '.child');
$('#target').html('Handler is bound to <code>document</code>.<br/> Click events will bubble through <code>div.clickCount</code> (even though the handler calls <code>e.stopPropagation()</code>).');
$(document).on('click', '.child', handler);
});
$('#parent').click(function () {
$('.parent').off('click', '.child');
$(document).off('click', '.child');
$('#target').html('Handler is bound to <code>.parent</code> nodes (black border).<br/>Click events won\'t bubble through <code>div.clickCount</code> (the handler calls <code>e.stopPropagation()</code> before the event reaches <code>div.clickCount</code>).');
$('.parent').on('click', '.child', handler);
});
//initially: bound to document
$(document).on('click', '.child', handler);