首页 > 代码库 > javaScript事件(一)事件流

javaScript事件(一)事件流

一、事件

事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字。
事件是javaScript和DOM之间的桥梁。
你若触发,我便执行——事件发生,调用它的处理函数执行相应的JavaScript代码给出响应。
典型的例子有:页面加载完毕触发load事件;用户单击元素,触发click事件。

二、事件流

1、事件流感性认识
问题:单击页面元素,什么样的元素能感应到这样一个事件?
答案:单击元素的同时,也单击了元素的容器元素,甚至整个页面。
例子:有三个同心圆, 给每个圆添加对应的事件处理函数,弹出对应的文字。单击最里面的圆,同时也单击了外面的圆,所以外面圆的click事件也会被触发。

<!DOCTYPE html><html><head lang="en">    <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>

2、事件流

事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。
事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事件流。
冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根。
捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title></head><body><div id="myDiv">Click me!</div></body></html>

 

 

上面这段html代码中,单击了页面中的<div>元素,
在冒泡型事件流中click事件传播顺序为<div> —> <body>—> <html>—> document
在捕获型事件流中click事件传播顺序为document —> <html> —><body> —> <div>

<!DOCTYPE html><html><head lang="en">    <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>    //true - 事件句柄在捕获阶段执行    //false- 事件句柄在冒泡阶段执行(默认)    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>

3、事件流的典型应用——事件代理

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><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;                console.log(targetElement.nodeName.toLowerCase());                if (targetElement.nodeName.toLowerCase() === "li") {                    alert(targetElement.innerHTML);                }            }        })();        </script>    </body></body></html>

a、将多个事件处理器减少到一个,因为事件处理器要驻留内存,这样就提高了性能。想象如果有一个100行的表格,对比传统的为每个单元格绑定事件处理器的方式和事件代理(即table上添加一个事件处理器),不难得出结论,事件代理确实避免了一些潜在的风险,提高了性能。

b、DOM更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。如果新增其他子元素(a,span,div等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。

javaScript事件(一)事件流