This time I will show you how to prevent event propagation in the front end, and what are the precautions to prevent event propagation in the front end. The following is a practical case, let's take a look.
Make a small demo, click the button to display the floating layer, click elsewhere to close the floating layer, and write a simple css
<style> .wrapper{ position:relative; display:inline-block; } .popover{ position:absolute; border:1px solid red; left:100%; top:0; padding:10px; margin-left:10px; background:white; display: none; /*默认隐藏*/ } .popover::before{ position:absolute; content:''; top:5px; right:100%; border:10px solid transparent; border-right-color:red; } .popover::after{ position:absolute; content:''; top:5px; right:100%; border:10px solid transparent; border-right-color:white; margin-right:-1px; } </style> <p id="wrapper" class='wrapper'> <button id="clickMe">点我</button> <p id="popover" class="popover"> <input type="checkbox">浮层 </p> </p> <script> clickMe.addEventListener('click',function(){ popover.style.display = 'block'; }); </script>
Now what if I click on a blank space on the page to close it? What method should be used? It is easy to think of monitoring documents, such as the following code
document.addEventListener('click',function(){ popover.stely.display = 'none'; });
. However, after actually writing it like this, the buttons are invalid and there is no response no matter how you click them. Why is this?
After understanding the capture and bubbling events mentioned in the previous article, you can easily understand this point, you can []().
We did not specify whether the monitoring is in the capturing or bubbling phase. The browser defaults to the bubbling phase. When we click the button, the capturing phase does not happen, but the bubbling phase is different. First button
The upper function is triggered first, and then the document
upper function is also triggered, causing the floating layer to appear to be hidden again.
Then you may want to ask, has the event on button
been executed? In fact, both events are executed, but the time is too short. The browser executes them together by default. You can add a debugger
inside and you can see it.
clickMe.addEventListener('click',function(){ popover.style.display = 'block'; });
So how to solve it? The simplest way is to, in addition to executing popover.style.display = 'block'
, also prevent the event from propagating
clickMe.addEventlistener('click',function(){ popover.style.display = 'block'; }); popover.addEventListener('click',function(e){ e.stopPropagation(); });
Why is it added to the parent element of the button here? If it is not added on the parent element, the floating layer will be closed when you click it.
If there are many listeners on the page, this method is a waste of memory. A more memory-saving method is to use JQuery
$(clickMe).on('click',function(){ $(popover).show(); $(document).one('click',function(){ $(popover).hide(); }); }); $(wrapper).on('click',function(e){ e.stopPropagation(); })
Do not listen at the beginning, only after popover
Listen once during `show` and turn it off immediately. This is called cleaning up the battlefield. $(wrapper).on('click',false)
is completely equivalent to the following code
$(wrapper).on('click',function(e){ e.preventDefault(); //阻止默认事件 e.stopPropagation(); //阻止传播 })
But if there is a checkbox
in the page, you If the organization default event is added to any layer of its parent element, including checkbox
itself, then this checkbox
cannot be check
.
There is a question here. If the propagation of the event is not prevented, what will happen as shown below?
$(clickMe).on('click',function(){ $(popover).show(); $(document).one('click',funtion(){ $(popover).hide(); }); });
Of course, as before, nothing will happen, so what happened when I clicked the button?
When I click the button, it will do two things. First, popover
`show will come out, and then the
hide function will be added to
documentAbove, when the event propagates to
document`, it will be hidden again.
You can add a setTimeout()
function to it to solve this problem
$(clickMe).on('click',function(){ $(popover).show(); setTimeout(function(){ $(document).one('click',function(){ $(popover).hide(); }) },0) });
setTimeout(fn,0)
This0
It is not executed immediately, but executed as soon as possible. Specifically, the function here is executed after the bubbling ends. In other words, when the bubbling ends, the listening event is added to document
and waits for the user Click to execute next time.
Summary:
Monitoring button
and document
at the same time, nothing happens when you click on it, because both functions are executed Well, the problem is solved by preventing event propagation, which is a waste of memory.
The best way is to use jQuery, and listen to document## after clicking the
button #, if it is closed, it will no longer listen, and it will not prevent the propagation of events, and nothing will happen when you click on it. There are two solutions: one is to prevent the propagation of events, and the other is to add a
setTimeout() function.
React-router v4 usage steps detailed explanation
Chart.js lightweight chart library use case Analysis
Chart.js lightweight HTML5 chart drawing tool library detailed steps to use
The above is the detailed content of How to prevent event propagation in the front end. For more information, please follow other related articles on the PHP Chinese website!