I have a calendar icon which has an onclick
handler that displays a popup calendar and I want to set it up so that clicking anywhere but on the calendar popup dismisses it.
However, it dismisses the popup immediately.
The example code demonstrates the problem:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</head>
<body>
<img src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' width='100px' onclick='fire()' />
<script>
function fire() {
console.log('fire');
$('body').on('click', (e) => {
console.log('clicked outside');
$('body').off('click');
});
}
</script>
</body>
</html>
So running the snippet above, outputs "fire" and then immediately "clicked outside" ... but why, i only attach the handler in the fire
function so how can it fire immediately?
The problem in your code is that both the calendar icon click event and the body click event are triggered when you click on the icon.
See : https://api.jquery.com/event.stopPropagation/
An event triggered on one element propagates to its parent elements. In your case, the icon click event immediately propagates to the body element.
You can stop the propagation of the calendar icon event :
function fire(event) {
console.log("fire");
// Stop the event from spreading
event.stopPropagation();
// Listen to clicks on the body
$("body").on("click", function () {
console.log("clicked outside");
// Remove the listener after it has been triggered
$("body").off("click");
});
}
Then, modify the HTML to pass the event object to your fire() function :
<img src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' width='100px' onclick='fire(event)' />
The click event on the calendar icon will not propagate to the body, and the click event on the body will only be triggered if you click outside the calendar icon !