Nesting event handlers
by dont_panic
HTML
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css">
<p><button class="btn btn-success">Click Me!</button></p>
<ul>
<li>On page load, there is only 1 event handler defined, the top-level one - it hasn't actually <i>run</i> yet, so the nested handler isn't yet defined.</li>
<li>On first click, the top-level handler runs, and defines the nested handler</li>
<li>On 2nd click, both handlers run, and a new copy of the nested handler is defined (there are now 2 copies of the nested handler).</li>
<li>On 3rd click, all 3 handlers run. The log shows the nested handler runs 2x. A new copy of the nested handler is added.</li>
<li>... and so on. Each click adds a new copy of the nested handler, and they <b>all run</b>.</li>
</ul>
<div class="row">
<div class="col-sm-6">
<div>
<b>Clicks</b>
<p id="clicks"></p>
</div>
</div>
<div class="col-sm-6">
<div>
<b>Events</b>
<p id="events"></p>
</div>
</div>
</div>
CSS
.col-sm-6 {
padding-top: 10px;
padding-bottom: 10px;
border: 1px solid #ccc;
}
JavaScript
let $clicks = $('#clicks'), clicks = 0
$events = $('#events'), topevents = 0, innerevents=0;
// Top-level event handler
$('button').on('click', function() {
clicks++;
topevents++;
$clicks.append('<br>Button click #' + clicks);
$events.append('<br>Top-level event handler run #' + topevents);
// Nested event handler
$('button').on('click', function() {
innerevents++;
$events.append('<br>Inner event handler run #' + innerevents);
});
});