DOM事件学习总结

一、事件流

所谓事件流就是描述从一个页面中接受事件的顺序。

1. 事件冒泡

事件冒泡,即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上转播至最不具体的节点(文档)。

2. 事件捕获

事件捕获和事件冒泡正好相反,它的思想是不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。

例如:


如果给body,div,button都绑定事件,按照事件冒泡的机制,当用户点击按钮时,button最先接收事件,然后逐级向上传播,div也响应事件,最后body也响应事件,而事件捕获的过程则相反,在实际的应用中,事件冒泡用的比较多。


二、事件处理程序

1. HTML事件处理程序

事件直接加在HTML结构里,这种事件处理程序的最大缺点就是HTML和JS代码紧密耦合,如果将来要修改事件处理程序则需要修改两个地方,非常麻烦,所以实际开发中基本摒弃了这种用法。


2. DOM0级事件处理程序

这是一种比较传统的方式,即把一个函数赋值给一个事件的处理程序属性,也是用的比较多的一种方式,它的优点就是简单,并且还具有跨浏览器的优势,而且也解决了上述第一种事件处理程序的缺点,在给事件添加处理程序之后,如果想删除这个事件,则给这个事件的处理程序属性赋值为空即可。


3.DOM2级事件处理程序

DOM2级事件定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。它们都接收三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(false为冒泡阶段调用,true为捕获阶段调用)。通过这种方式可以给一个元素添加多个事件处理程序,这些事件处理程序会按照添加时的顺序在触发后依次执行。


在添加删除语句之前的执行结果:


4. IE事件处理程序

IE事件处理程序提供了类似DOM2级的方法:attachEvent()添加事件,detachEvent()删除事件。这两个方法接收相同的两个参数:事件处理程序名称与事件处理函数。之所以没有第三个参数是因为IE8以及更早的浏览器版本只支持事件冒泡机制。


5. 跨浏览器的事件处理程序

为了解决浏览器兼容问题,我们需要编写一个能跨浏览器的事件处理程序,其思想就是能力检测,判断你是否有这个功能,如果有就执行。

<!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>事件处理程序</title>
</head>

<body>
  <div id="wrap">
    <button id="btn">按钮</button>
  </div>
  <script type="text/javascript">
    var bindEvent = {
      //添加事件
      addEvent: function (elem, type, fn) {
        if (elem.addEventListener) {
          elem.addEventListener(type, fn, false);
        } else if (elem.attachEvent) {
          elem.attachEvent('on' + type, fn); //由于IE的参数是要加'on'的
        } else {
          elem['on' + type] = fn;
        }
      },
      //删除事件
      removeEvent: function (elem, type, fn) {
        if (elem.removeEventListener) {
          elem.removeEventListener(type, fn, false);
        } else if (elem.detachEvent) {
          elem.detachEvent('on' + type, fn);
        } else {
          elem['on' + type] = null;
        }
      }
    }

    var btn = document.getElementById('btn');
    function showValue() {
      console.log(this.innerHTML);
    }

    bindEvent.addEvent(btn, 'click', showValue);
  </script>
</body>

</html>

三、事件对象event

在触发DOM上的事件时都会产生的一个对象,可以在浏览器中打印出来看看这个对象都包含哪些内容。我这里通过一个点击事件打印出事件对象,只截取了一部分:


1. DOM中的事件对象

通过以上截图可以看到这个事件对象包含各种信息,这里比较常用的属性和方法是以下几种:

(1)、type:获取事件类型

(2)、target:事件目标



(3)、stopPropagation() 阻止事件冒泡

给button添加一个事件,打印按钮,给父元素div添加一个事件,打印容器。当我不阻止事件冒泡时,点击按钮,会触发两个事件:



把代码的注释去掉,即阻止事件冒泡,这时只打印按钮:


(4)、preventDefault() 阻止事件的默认行为

给a标签添加个点击事件,打印一些信息,如果不阻止事件默认行为,那么在打印信息后,会跳转到href属性里写的地址的页面,当我们不想让页面发生跳转,只想打印一些信息时,就需要阻止事件的默认行为:


2. IE中的事件对象
(1)、type:获取事件类型
(2)、srcElement:事件目标
(3)、cancelBubble=true阻止事件冒泡

(4)、returnValue=false阻止事件的默认行为

代码与DOM中的类似,只是调用的属性不同。

3. 事件的跨浏览器处理程序完整版
var bindEvent = {
  //添加事件
  addEvent: function (elem, type, fn) {
    if (elem.addEventListener) {
      elem.addEventListener(type, fn, false);
    } else if (elem.attachEvent) {
      elem.attachEvent('on' + type, fn); //由于IE的参数是要加'on'的
    } else {
      elem['on' + type] = fn;
    }
  },
  //删除事件
  removeEvent: function (elem, type, fn) {
    if (elem.removeEventListener) {
      elem.removeEventListener(type, fn, false);
    } else if (elem.detachEvent) {
      elem.detachEvent('on' + type, fn);
    } else {
      elem['on' + type] = null;
    }
  },
  getEvent: function (event) {
    return event ? event : window.event;
  },
  getType: function (event) {
    return event.type;
  },
  getElement: function (event) {
    return event.target || event.srcElement;
  },
  preventDefault: function (event) {
    if (event.preventDefault) {
      event.preventDefault();
    } else {
      event.returnValue = false;
    }
  },
  stopPropagation: function (event) {
    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true;
    }
  }
}

使用:

<!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>DOM事件</title>
  <script src="event.js"></script>
  <script src="script.js"></script>
</head>

<body>

  <body>
    <div id="box">
      <a href="event.html" id="go">跳转</a>
    </div>
  </body>
</body>

</html>
window.onload = function () {
  var go = document.getElementById('go'),
    box = document.getElementById('box');

  bindEvent.addEvent(box, 'click', function () {
    alert('我是整个父盒子');
  });

  bindEvent.addEvent(go, 'click', function (e) {
    // e = eventUtil.getEvent(e);
    e = e || window.event;
    alert(bindEvent.getElement(e).nodeName);
    bindEvent.preventDefault(e);
    bindEvent.stopPropagation(e);
  });

}
以上就是我学习DOM事件的一些总结,如有不对的地方欢迎大家指正,共同进步!后续会写一些事件冒泡的实际应用。

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值