DOM事件详解

2020-12-13  本文已影响0人  amanohina

绑定事件方法

注册事件的其他方法1

  btn.addEventListener("click",function(){
      alert("1");
    });
// 多次绑定相同的事件类型,事件会根据书写的顺序进行事件的排队
    btn.addEventListener("click",clickEvent);
    function clickEvent() {
      alert("2");
    }

注册事件的其他方法2

var btn = document.getElementById("btn");    
    // DOM 2 级事件绑定方式
    // 兼容:IE 10 及以下浏览器
    // IE8 及以下的浏览器处理事件队列时,会出现顺序错乱
    btn.attachEvent("onclick",function () {
      alert(3);
    });
    btn.attachEvent("onclick",clickEvent);
    function clickEvent() {
      alert(4);
    }

IE8及以下浏览器处理事件队列的时候会出现顺序错乱

注册事件兼容写法

  <script>
    var btn = document.getElementById("btn");
    // DOM 2 级事件绑定方式
    // 调用函数
    addEvent(btn,"click",function(){
      alert("1")
    });
    // 自己制作一个兼容所有浏览器的绑定事件的函数
    // 参数:事件源,事件类型,事件函数
    function addEvent(ele,type,fn){
      // 判断,IE 9 及以上和其他浏览器,使用addEVentListener
      // IE 9 及以下的浏览器,使用attachEvent
      // 浏览器能力监测
      if(ele.addEventListener){
        ele.addEventListener(type,fn);
      }else if(ele.attachEvent){
        ele.attachEvent("on"+type,fn);
      }
    }
    </script>

移除事件

移除事件的其他方法1

移除绑定的语句必须要在绑定事件语句之后进行

<script>
    var btn = document.getElementById("btn");
    // 绑定事件
    // btn.onclick = function(){
    //   alert(1);
    // };
    // // 解除绑定方法:
    // btn.onclick = null;

    // 绑定事件
    btn.addEventListener("click",fun);
    btn.addEventListener("click",fun2);
    function fun2(){
      alert(2);
    }
    function fun(){
      alert(1);
    }
    // 解除绑定
    btn.removeEventListener("click",fun);
    btn.removeEventListener("click",fun2);
    </script>

移除事件的其他方法2

// 绑定事件
    btn.attachEvent("onclick",fun);
    btn.attachEvent("onclick",fun2);
    // btn.detachEvent("onclick",fun);
    function fun(){
      alert(2);
    }
    function fun2(){
      alert(3);
    }

解除事件兼容写法

// 兼容所在浏览器的解除绑定事件的函数
    // 参数:事件源,事件类型,事件函数
    function removeEvent(ele,type,fn){
      // 浏览器能力监测
      if(ele.removeEventListener){
        ele.removeEventListener(type,fn);
      }else if(ele.detachEvent){
        ele.detachEvent("on"+type,fn);
      }
    }

将绑定和解除事件兼容的写法封装到js库内,如下:(获取id,绑定事件,解除事件)

// 定义一个获取元素的函数
function my$(id) {
  return document.getElementById(id);
}

// DOM 2 级事件绑定方式
// 自己制作一个兼容所有浏览器的绑定事件的函数
// 参数:事件源,事件类型,事件函数
function addEvent(ele, type, fn) {
  // IE 9 及以上的浏览器和其他浏览器,使用 addEventListener 方法
  // IE 9 以下的浏览器,使用 attachEvent 方法
  // 浏览器能力检测
  if (ele.addEventListener) {
    ele.addEventListener(type, fn);
  } else if (ele.attachEvent) {
    ele.attachEvent("on" + type, fn);
  }
}

// 兼容所有浏览器的 解除绑定事件的函数
// 参数:事件源,事件类型,事件函数
function removeEvent(ele, type, fn) {
  // 浏览器能力检测
  if (ele.removeEventListener) {
    ele.removeEventListener(type, fn);
  } else if (ele.detachEvent) {
    ele.detachEvent("on" + type, fn);
  }
}

DOM事件流

事件流,先捕获,再冒泡
<script>
        var box1 = document.getElementById("box1");
        var box2 = document.getElementById("box2");
        var box3 = document.getElementById("box3");

        // 添加点击事件
        // addEventListener有第三个参数,用来决定事件流的方向
        // 参数值是布尔值,false表示事件流是按照事件冒泡的过程执行的,true表示事件捕获过程
        // 参数的默认值是false,默认为时间冒泡过程
        box1.addEventListener("click",function(){
            console.log(this.id);
        });
        box2.addEventListener("click",function(){
            console.log(this.id);
        });
        box3.addEventListener("click",function(){
            console.log(this.id);
        });

        box1.addEventListener("click",function(){
            console.log(this.id);
        },true);
        box2.addEventListener("click",function(){
            console.log(this.id);
        },true);
        box3.addEventListener("click",function(){
            console.log(this.id);
        },true);

        // 冒泡过程和捕获过程一起执行是先进行捕获,再进行冒泡
    </script>
显而易见,先捕获,再冒泡

事件流的三个阶段

事件冒泡的应用——事件委托

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            width: 300px;
            border: 1px dashed #f0f;
            margin: 50px auto;
            font-size: 24px;
            line-height: 48px;
            list-style: none;
        }
        li {
            padding-left: 20px;
            cursor: pointer;
        }

    </style>
</head>

<body>
    <ul id="list">
        <li>刘亦菲</li>
        <li>杨幂</li>
        <li>唐嫣</li>
        <li>赵丽颖</li>
        <li>刘诗诗</li>
    </ul>
    <script>
        // 让每个 li 被点击后,自己添加特殊的背景色,而其他兄弟不添加
        // 以前的思路,获取所有的li标签元素,然后批量添加事件
        // 事件委托原理:可以将一些子级的公共类型的事件委托给父级添加,然后在父级内部想办法找到真正触发事件的最底层的事件源
        // 获取元素
        var list = document.getElementById("list");
        var lis = list.children;
        // 事件委托的过程,给ul添加点击事件
        list.onclick = function(e){
            // 内部要想办法找到真正触发事件的li
            // 借用事件函数内部的一个参数,e是事件对象
            // 只要触发了事件,这时候函数内部他都可以得到一个事件对象,对象中存储了关于事件的一系列数据
            // e.target 这个属性记录的就是真正触发的事件的事件源
            // 排除其他
            for(var i = 0;i<lis.length;i++){
                lis[i].style.backgroundColor = "";
            }
            e.target.style.backgroundColor = "pink";
        };
    </script>
</body>

</html>

事件对象

 box1.onclick = function (e) {
// 获取绑定事件的事件源元素
            console.log(e.currentTarget);
}

box1就是事件源

也可以用this代替指向

e.type——获取事件类型

// 可以将所有给一个元素绑定的事件的事件函数写在一个函数内,通过函数内部的e.type判断走不同的分支
    // 避免添加多个函数,占用更多的内存
    
    box1.onmouseover = fn;
    box1.onmouseout = fn;

    function fn(e){
        e = e || window.event;
        // 根据事件类型执行不同的代码
        switch(e.type){
            case "mouseover":
                box1.style.backgroundColor = "skyblue";
                break;
            case "mouseout":
                box1.style.backgroundColor = "yellowgreen";
                break;
        }
    }

e.clientX/e.cilentY——所有浏览器都支持,鼠标距离浏览器窗口左上角的距离
e.pageX/e.pageY——IE8以前不支持,鼠标距离整个HTML页面左上顶点的距离

// 事件对象中有一些获取尺寸的属性
        box1.onclick = function(e){
            // client系列:客户端尺寸,点击的点参考浏览器窗口左上角的距离,跟自己页面的左上角没有关系
            console.log(e.clientX);
            console.log(e.clientY);
            // page系列,html页面尺寸,点击的点参考HTML文档左上角的距离
            console.log(e.pageX);
            console.log(e.pageY);

事件对象案例:图片跟随鼠标移动而移动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      #pic {
        position: fixed;
      }
    </style>
</head>
<body>
    <img src="images/tianshi.gif" alt="" id="pic">
    <script>
      //  通过鼠标移动事件给图片添加left和top值
      // 获取元素
      var pic = document.getElementById("pic");
      // 添加鼠标移动事件(给整个文档)
      document.onmousemove = function(e){
        e = e || window.event;
        // 给pic元素css属性赋值
        pic.style.left = e.clientX + "px";
        pic.style.top = e.clientY + "px";
      };
    </script>
</body>
</html>

取消默认行为和阻止冒泡(阻止事件传播)

<body>
  <a id="link" href="52_图片跟随鼠标移动效果.html">点击</a>
  <script>
    var link = document.getElementById('link');
    link.onclick = function (e) {
      e = e || window.event;
      alert('hello');
      // 普通的方式阻止默认行为
      // return false;
      // DOM 的方法
      // e.preventDefault();
      // 低版本浏览器需要使用一个对象的属性
      e.returnValue = false;
    }
  </script>
</body>
<script>
    // 事件冒泡
    var box1 = document.getElementById('box1');
    var box2 = document.getElementById('box2');
    var box3 = document.getElementById('box3');

    var array = [box1, box2, box3];

    for (var i = 0; i < array.length; i++) {
      var box = array[i];
      box.onclick = function (e) {
        e = e || window.event;
        console.log(this.id);
        // 阻止事件冒泡
        // e.stopPropagation();
        // 低版本浏览器使用 属性
        e.cancelBubble = true;
      }
    }
  </script> 

其他常见事件类型

参考资料:

https://developer.mozilla.org/zh-CN/docs/Web/Events

上一篇下一篇

猜你喜欢

热点阅读