Web APIs---6. DOM事件高级(1)

1 注册事件(绑定事件)

1.1 注册事件概述

给元素添加事件,称为注册事件或者绑定事件。注册事件有两种方式:传统方式和方法监听注册方式

传统注册方式
  • 利用on开头的事件,eg:onclick,
<button onclick="alert('hi~')"></button>//传统方式1
btn.onclick = function(){}//传统方式2
  • 特点:注册事件的唯一性,即同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
方法监听注册方式
  • w3c标准的推荐方式,利用addEventListener()方法实现
  • IE9之前的IE不支持此方法,可以使用attachEvent()代替
  • 特点:同一个元素同一个事件可以注册多个监听器,会按照注册顺序依次执行,不会有唯一性的问题

1.2 addEventListener 事件监听方式(ie9之后)

eventTarget.addEventListener(type, listener[, useCapture])//将指定的监听器(函数)注册到目标对象(eventTarget)上,当该对象触发指定事件时,就会执行事件处理函数。
  • type:事件类型,该参数是字符串,比如:click、mouseover,注意这里不要带on
  • listener:事件处理函数,事件发生时,会调用该监听函数
  • userCapture:可选参数,是一个布尔值,默认是false。

1.3 attachEvent 事件监听方式(ie9以前)

该特性非标准,不要在生成环境中使用。该特性仅仅作为了解即可。只有ie浏览器可以识别,而且一定要ie9以前的浏览器。

eventTarget.attachEvent(eventNameWithOn, callback)//将指定的监听器(函数)注册到目标对象(eventTarget)上,当该对象触发指定的事件,指定的回调函数就会被执行。
  • eventNameWithOn:事件类型,该参数是字符串,比如onclick、onmouseover,注意这里要带on
  • callback:事件处理函数,当目标触发事件时回调函数被调用
以上3种方法举例
<body>
    <button>传统注册事件</button>
    <button>方法监听注册事件</button>
    <button>ie9 attachEvent</button>
    <script>
        var btns = document.querySelectorAll('button');
        //1. 传统方式注册事件
        btns[0].onclick = function() {
            alert('hi~');
        }
        btns[0].onclick = function() {
                alert('hao a u~');
            } //点击按钮后只会出现hao a u ~,前面的hi~被覆盖掉了,传统方法注册事件具有唯一性

        //2. 事件监听注册事件
        btns[1].addEventListener('click', function() {
            alert('22');
        })
        btns[1].addEventListener('click', function() {
                alert('33');
            }) //点击按钮后会先后弹出对话框22和33,后面的函数不会覆盖前面的函数

        //3. attachEvent ie9以前版本支持
        btns[2].attachEvent('onclick', function() {
            alert(11);
        })
    </script>
</body>

1.4 兼容性处理方案(了解)

2 删除事件(解绑事件)

2.1 删除事件的方式

传统解绑事件方式
eventTarget.onclick = null;
方法监听解绑事件的方式
eventTarget.removeEventListener(type, listener[, useCapture]);
方法监听解绑事件的方式(仅适用于ie678)
eventTarget.detachEvent(eventNameWithOn, callback)
以上三种方法举例
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        var divs = document.querySelectorAll('div');
        //1. 传统方式解绑事件
        divs[0].onclick = function() { //点击第一个div盒子弹出一次11,之后再点第一个div盒子就不会弹出任何内容了
            alert(11);
            divs[0].onclick = null;
        }

        //2. 方法监听解绑事件的方式
        divs[1].addEventListener('click', fn) //考虑到接下来要移除,则不能采取匿名函数的方法,而且只要写一个函数名fn就可以了,不用加小括号fn()
        function fn() {
            alert(22);
            divs[1].removeEventListener('click', fn);
        }

        //3. 专门针对于ie678的解绑方式
        divs[2].attachEvent('onclick', fn1);

        function fn1() {
            alert(33);
            divs[2].detachEvent('onclick', fn1);
        }
    </script>
</body>

2.2 删除事件兼容性问题解决方案(了解)

3 DOM事件流

  • 事件流:事件发生时会在元素节点之间按照特定的的顺序传播,这个传播过程即为DOM事件流
  • 事件流理解
注意
  • JS代码中只能执行捕获或者冒泡其中的一个阶段
  • onclick和attachEvent只能得到冒泡阶段
  • addEventListener(type,listener[,useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写就默认是false),表示在事件冒泡阶段调用事件处理程序。
  • 实际开发中很少使用事件捕获,更关注事件冒泡
  • 有些事件是没有冒泡的,比如:onblur、onfocus、onmouseenter、onmouseleava
捕获
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        //dom事件流三个阶段
        //1. JS代码中只能执行捕获或者冒泡其中一个阶段。
        //2. onclick和attachEvent(ie)只能得到冒泡阶段
        //3. addEventListener【第三个参数是true】 捕获阶段:document->html->body->father->son 从上到下依次检测是否添加了点击事件,若添加了则依次执行,所以点击father盒子将弹出father之后就结束了;点击son盒子,将先弹出father,再弹出son
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, true);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, true);
    </script>
</body>
冒泡
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        //dom事件流三个阶段
        //1. JS代码中只能执行捕获或者冒泡其中一个阶段。
        //2. onclick和attachEvent(ie)只能得到冒泡阶段

        //4. addEventListener【第三个参数是false或省略】 冒泡阶段:document<-html<-body<-father<-son 从下到上依次检测是否添加了点击事件,若添加了则依次执行,点击son盒子将先弹出son,再弹出father;点击father盒子之后弹出father就结束了
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
    </script>
</body>
//捕获:点击到哪个盒子就检查执行到哪个盒子
//冒泡:点击到哪个盒子就从这个盒子开始检查执行
原文地址:https://www.cnblogs.com/deer-cen/p/12240522.html