Reputation: 13
I have a plain webpage with a singe button.
Using jQuery 3.3.1, a 'click' event is attached to this button such that once this button is clicked, the next click anywhere on the page(document
) makes an alert('Clicked!')
.
<div id="container">
<button id="Btn">Click</button>
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#Btn").click(function() {
$(document).click(function() {
alert("Clicked!");
$(document).unbind('click');
});
});
});
</script>
But using this code, the first click on the button itself makes the alert('Clicked!')
.
I changed the code a bit and attached the 'click' event to $(document)
inside a nested $(document).ready()
:
<script type="text/javascript">
$(document).ready(function() {
$("#Btn").click(function() {
$(document).ready(function() { // <--here
$(document).click(function() {
alert("Clicked!");
$(document).unbind('click');
});
});
});
});
</script>
This works as intended but I still can't infer such behaviour: why do I need to include a nested $(document).ready()
?
Or is there any other approach to achieve the desired functionality?
Upvotes: 1
Views: 1201
Reputation: 14541
The reason your first snippet generates alert on the first click on button is event propagation, specifically event bubbling. When you click the button, after the event handler has executed, the same event propagates up the DOM tree; eventually it reaches the document element, and triggers the new event handler that you subscribe to.
One of the approaches to ensure that the event doesn't immediately trigger at document would be to prevent the propagation of the event by calling event.stopPropagation()
.
You can see that in action in the snippet below:
$(document).ready(function() {
$("#Btn").click(function(e) {
e.stopPropagation();
$(document).click(function() {
alert("Clicked!");
$(document).unbind('click');
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<button id="Btn">Click</button>
</div>
Upvotes: 2