This chapter brings you what are javaScript event stream events? (Introduction), so that everyone can understand what javaScript events and event streams are. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
1. javaScript events
Events are specific moments of interaction that occur in a document or browser window.
An event is a certain action performed by the user or the browser itself, such as click, load and mouseover are the names of the events.
Events are the bridge between javaScript and DOM.
If you trigger it, I will execute it - when the event occurs, its handler function is called to execute the corresponding JavaScript code to give a response.
Typical examples include: the load event is triggered when the page is loaded; the click event is triggered when the user clicks on an element.
2. Event flow
The event flow describes the order in which events are received from the page.
1. Event flu awareness
Question: When you click on a page element, what kind of element can sense such an event?
Answer: When you click on an element, you also click on the container element of the element, or even the entire page.
Example: There are three concentric circles. Add the corresponding event processing function to each circle and pop up the corresponding text. When you click the innermost circle, you also click the outer circle, so the click event of the outer circle will also be triggered.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <style> #outer{ position: absolute; width: 400px; height: 400px; top:0; left: 0; bottom:0; right: 0; margin: auto; background-color: deeppink; } #middle{ position: absolute; width: 300px; height:300px; top:50%; left: 50%; margin-left: -150px; margin-top: -150px; background-color: deepskyblue; } #inner{ position: absolute; width: 100px; height:100px; top:50%; left:50%; margin-left: -50px; margin-top: -50px;; background-color: darkgreen; text-align: center; line-height: 100px; color:white; } #outer,#middle,#inner{ border-radius:100%; } </style> <body> <div id="outer"> <div id="middle"> <div id="inner"> click me! </div> </div> </div> <script> var innerCircle= document.getElementById("inner"); innerCircle.onclick= function () { alert("innerCircle"); }; var middleCircle= document.getElementById("middle"); middleCircle.onclick=function(){ alert("middleCircle"); } var outerCircle= document.getElementById("outer"); outerCircle.onclick= function () { alert("outerCircle"); } </script> </body> </html>
Rendering:
2. Event flow
When an event occurs, it will be propagated in a specific order between the element node and the root node. All nodes along the path will receive the event. This propagation process is the DOM event stream.
1) Two event flow models
The order of event propagation corresponds to the two event flow models of the browser: capturing event flow and bubbling event flow.
Bubble event flow: The propagation of events is from the most specific event target to the least specific event target. That is, from the leaves of the DOM tree to the root. [Recommendation]
Capture-type event flow: The propagation of events is from the least specific event target to the most specific event target. That is, from the root of the DOM tree to the leaves.
The idea of event capture is that less specific nodes should receive events earlier, and the most specific nodes should receive events last.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="myDiv">Click me!</div> </body> </html>
In the above HTML code, the
The order of click event propagation in the bubbling event stream is
In the capture event stream, the order of click event propagation is document—》—》
—》note:
All modern browsers support event bubbling, but there are slight differences in the specific implementation:
IE5 In .5 and earlier versions, event bubbling will skip the element (jump directly from body to document).
IE9, Firefox, Chrome, and Safari bubble the event all the way to the window object.
2), IE9, Firefox, Chrome, Opera, and Safari all support event capture. Although the DOM standard requires that events should be propagated from the document object, these browsers capture events from the window object.
3). Since old versions of browsers do not support it, few people use event capture. It is recommended to use event bubbling.
2) DOM event flow
DOM standard adopts capture bubbling. Both event streams will trigger all objects in the DOM, starting with and ending with the document object.
The DOM standard stipulates that the event flow includes three stages: the event capture stage, the target stage and the event bubbling stage.
Event capture phase: The actual target (
is in the target stage: events occur and are processed on
Bubbling phase: The event is propagated back to the document.
note:
尽管“DOM2级事件”标准规范明确规定事件捕获阶段不会涉及事件目标,但是在IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两次机会在目标对象上面操作事件。
并非所有的事件都会经过冒泡阶段 。所有的事件都要经过捕获阶段和处于目标阶段,但是有些事件会跳过冒泡阶段:如,获得输入焦点的focus事件和失去输入焦点的blur事件。
两次机会在目标对象上面操作事件例子:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <style> #outer{ position: absolute; width: 400px; height: 400px; top:0; left: 0; bottom:0; right: 0; margin: auto; background-color: deeppink; } #middle{ position: absolute; width: 300px; height:300px; top:50%; left: 50%; margin-left: -150px; margin-top: -150px; background-color: deepskyblue; } #inner{ position: absolute; width: 100px; height:100px; top:50%; left:50%; margin-left: -50px; margin-top: -50px;; background-color: darkgreen; text-align: center; line-height: 100px; color:white; } #outer,#middle,#inner{ border-radius:100%; } </style> <body> <div id="outer"> <div id="middle"> <div id="inner"> click me! </div> </div> </div> <script> var innerCircle= document.getElementById("inner"); innerCircle.addEventListener("click", function () { alert("innerCircle的click事件在捕获阶段被触发"); },true); innerCircle.addEventListener("click", function () { alert("innerCircle的click事件在冒泡阶段被触发"); },false); var middleCircle= document.getElementById("middle"); middleCircle.addEventListener("click", function () { alert("middleCircle的click事件在捕获阶段被触发"); },true); middleCircle.addEventListener("click", function () { alert("middleCircle的click事件在冒泡阶段被触发"); },false); var outerCircle= document.getElementById("outer"); outerCircle.addEventListener("click", function () { alert("outerCircle的click事件在捕获阶段被触发"); },true); outerCircle.addEventListener("click", function () { alert("outerCircle的click事件在冒泡阶段被触发"); },false); </script> </body> </html>
运行效果就是会陆续弹出6个框,为说明原理我整合成了一个图:
3、事件流的典型应用事件代理
传统的事件处理中,需要为每个元素添加事件处理器。js事件代理则是一种简单有效的技巧,通过它可以把事件处理器添加到一个父级元素上,从而避免把事件处理器添加到多个子级元素上。
1)事件代理
事件代理的原理用到的就是事件冒泡和目标元素,把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理。关于target更多内容请参考javaScript事件(四)event的公共成员(属性和方法) 下面举例来说明。
传统事件处理,为每个元素添加事件处理器,代码如下:
<body> <ul id="color-list"> <li>red</li> <li>orange</li> <li>yellow</li> <li>green</li> <li>blue</li> <li>indigo</li> <li>purple</li> </ul> <script> (function(){ var colorList=document.getElementById("color-list"); var colors=colorList.getElementsByTagName("li"); for(var i=0;i<colors.length;i++) { colors[i].addEventListener('click',showColor,false); }; function showColor(e) { e=e||window.event; var targetElement=e.target||e.srcElement; alert(targetElement.innerHTML); } })(); </script> </body>
事件代理的处理方式,代码如下:
<body> <ul id="color-list"> <li>red</li> <li>orange</li> <li>yellow</li> <li>green</li> <li>blue</li> <li>indigo</li> <li>purple</li> </ul> <script> (function(){ var colorList=document.getElementById("color-list"); colorList.addEventListener('click',showColor,false); function showColor(e) { e=e||window.event; var targetElement=e.target||e.srcElement; if(targetElement.nodeName.toLowerCase()==="li"){ alert(targetElement.innerHTML); } } })(); </script> </body>
2)事件代理的好处
总结一下事件代理的好处:
将多个事件处理器减少到一个,因为事件处理器要驻留内存,这样就提高了性能。想象如果有一个100行的表格,对比传统的为每个单元格绑定事件处理器的方式和事件代理(即table上添加一个事件处理器),不难得出结论,事件代理确实避免了一些潜在的风险,提高了性能。
DOM更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。如果新增其他子元素(a,span,div等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。
3)事件代理的问题:【update20170502】
代码如下:事件代理同时绑定了li和span,当点击span的时候,li和span都会冒泡。
<li><span>li中的span的内容</span></li> <script> $(document).on('click', 'li', function(e){ alert('li li'); }); $(document).on('click', 'span', function(e){ alert('li span'); }) </script>
解决办法:
方法一:span的事件处理程序中阻止冒泡
$(document).on('click', 'span', function(e){ alert('li span'); e.stopPropagation(); })
方法二:li的事件处理程序中检测target元素
$(document).on('click', 'li', function (e) { if (e.target.nodeName == 'SPAN') { e.stopPropagation(); return; } alert('li li'); });
4)事件代理的一个有趣应用【update20170502】
点击一个列表时,输出对应的索引
<script> var ul=document.querySelector('ul'); var lis=ul.querySelectorAll('ul li'); ul.addEventListener('click', function (e) { var target= e.target; if(target.nodeName.toUpperCase()==='LI'){ alert([].indexOf.call(lis,target)); } },false) </script>
The above is the detailed content of What are javaScript event stream events? (introduce). For more information, please follow other related articles on the PHP Chinese website!