I'm trying to stop a particular click event from bubbling to document-root, which in result closes one of my popup. I need to stop bubbling of the event and body
or html
are my only options to intercept and stop it.
The date-picker popup is generated on the fly so I cannot use a direct event on .ui-icon
element, so I have registered a delegate event on body
element to stop it from bubbling.
(function ($) {
$(function () {
$('body').on('click', '.ui-icon', function (e) {
e.stopPropagation();
});
});
})(jQuery);
Surprisingly enough registering a direct event to body
element and checking the event's target works just fine.
(function ($) {
$(function () {
$('body').on('click', function (e) {
if ($(e.target).is('.ui-icon')) {
e.stopPropagation();
}
});
});
})(jQuery);
I am really at a loss, why the previous one does not work where the later does, both of them are supposed to do the same. What am I missing? It might have to do with jQuery datepicker getting recomposed (its whole content block is rebuilt on navigation) before the event reaches body (but it does not make sense)?
Snippet with the issue is added below. I just want the arrows (datepicker navigation) to stop bubbling to document/root level (which closes my popup) and because datepicker gets appended to body, the only available intercept points are body/html.
$(function() {
let popup = $('#some-popup').addClass('visible');
let input = $('#some-date');
let toggler = $('#toggler');
// binding popup
toggler.on('click', function(e) {
e.stopPropagation();
popup.toggleClass('visible');
});
// initializing jQuery UI datepicker
input.datepicker();
// closing popup on document clicks other than popup itself
$(document).on('click', function(e) {
let target = $(e.target);
if (target.is('.ui-icon, .ui-datepicker-prev, .ui-datepicker-next')) {
console.warn('shouldn\'t have reached this, got: ' + target.attr('class'));
}
if (!(target.is('#some-popup'))) {
popup.removeClass('visible');
}
});
// trying to prevent click from reaching document
$('body').on('click', '.ui-icon, .ui-datepicker-prev, .ui-datepicker-next', function(e) {
e.stopPropagation();
})
});
#some-popup {
padding: 15px 25px;
background: #000;
color: #fff;
display: none;
max-width: 200px;
}
#some-popup.visible {
display: block;
}
#toggler {
margin-bottom: 10px;
}
<head>
<link href="https://code.jquery.com/ui/1.11.4/themes/black-tie/jquery-ui.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
</head>
<body>
<div id="some-popup">
This is the popup
</div>
<button type="button" id="toggler">Show/Hide Popup</button>
<form>
<label for="some-date">The Date-Picker</label>
<input id="some-date" onclick="event.stopPropagation();" />
</form>
</body>