zoukankan      html  css  js  c++  java
  • 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等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。

  • 相关阅读:
    面向对象与原型2---原型
    JavaScript 引用【转】
    面向对象与原型1---创建对象的方法
    匿名函数和闭包(下)
    从输入 URL 到页面加载完的过程中都发生了什么事情?
    匿名函数和闭包(上)
    聚美优品前端开发面试题
    hdoj1045 Fire Net(二分图最大匹配)
    hdoj1180 诡异的楼梯(bfs+奇偶判断)
    hdoj1373 Channel Allocation(极大团)
  • 原文地址:https://www.cnblogs.com/lgxlsm/p/6211932.html
Copyright © 2011-2022 走看看