一, 基本概念
1, 事件: 用户 / 浏览器自身执行的某种动作 (点击 click, 加载 load, 页面滚动 scroll 的等);
2, 事件处理程序: 响应某个事件的处理函数, 又叫事件侦听器
二, 事件流
事件流
1, 事件冒泡
由 IE 提出
由下向上
2, 事件捕获
由 Netscape 团队提出
由上向下
由于老版本浏览器不支持, 所以很少使用
3,DOM 事件流
DOM2 级事件
分为三个阶段: 事件捕获阶段, 处于目标阶段, 事件冒泡阶段
IE8 及更早版本不支持, 目前最常用的事件流
三, 绑定事件处理函数的方式
event: 事件对象 this: 指向事件目标
(一),html 上绑定
<li onclick="alert(this)">1 行 </li>
(二),js 中绑定
三种方式
方式一 DOM0 级方法
- var ele = document.getElementsByTagName('li')[0];
- // 绑定
- ele.onclick = function (event) {
- console.log(event);
- };
- // 同时给一个元素相同事件绑定两个事件处理函数时, 后面的代码会覆盖前面的
- ele.onclick = function (event) {
- console.log(this);
- };
- // 解绑
- ele.onclick = null;
这种方式不能同时绑定多个事件
方式二 DOM2 级方法
addEventListener 与 removeEventListener
- function handler1(event) {
- console.log(this);
- }
- function handler2(event) {
- console.log(event);
- }
- // 三个参数 1. 一个 / 多个事件 2. 事件处理函数 3. 响应阶段 (捕获阶段: true, 冒泡阶段: false 一般使用 false)
- ele.addEventListener('click', handler1, false);
- // 同时为同一个元素的同一个事件绑定多个处理函数时, 不会覆盖, 会按照绑定顺序执行
- ele.addEventListener('click', handler2, false);
- // 解绑 三个参数必须和绑定时保持一致才可以解绑
- ele.removeEventListener('click', handler1, false);
注: 1, 解绑函数的参数必须和绑定时的参数保持一致才能解绑; 2, 所以最好不要使用匿名函数, 不然解绑不了; 3, 同时为同一个元素的同一个事件绑定多个处理函数时, 不会覆盖, 会按照绑定顺序执行.
方式三 IE (ie8 以前只支持这种冒泡方式)
attachEvent 与 detachEvent
- // 绑定 两个参数 1.on'事件' 2. 事件处理函数
- ele.attachEvent('onclick', handler1);
- ele.attachEvent('onclick', handler2);
- // 解绑
- ele.detachEvent('onclick', handler1);
注: 1, 解绑函数的参数必须和绑定时的参数保持一致才能解绑; 2, 所以最好不要使用匿名函数, 不然解绑不了; 3, 同时为同一个元素的同一个事件绑定多个处理函数时, 不会覆盖, 会按照绑定顺序 相反的顺序 执行. 4,this 不指定事件目标而是指向 window,event 对象和前两种的 event 构成也不一样
四, 兼容 IE8 及以下浏览器事件绑定程序
- var handler = function(event) {
- console.log('事件类型:'+event.type+'事件阶段:'+event.eventPhase);
- }
- // 封装兼容事件绑定程序
- var EventUtil = {
- // 绑定事件处理函数
- addHandler: function (element, type, handler) {
- if(element.addEventListener) {
- element.addEventListener(type, handler, false);
- } else if(element.attachEvent) {
- element.attachEvent('on'+type, handler);
- } else {
- element['on'+type] = handler;
- }
- },
- // 解绑处理
- removeHandler: function (element, type, handler) {
- if(element.removeEventListener) {
- element.removeEventListener(type, handler, false);
- } else if(element.detachEvent) {
- element.detachEvent('on'+type, handler);
- } else {
- element['on'+type] = null;
- }
- },
- // 获取事件对象
- getEvent: function (event) {
- return event ? event : window.event;
- },
- // 获取事件目标元素
- getTarget: 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.cancleBubble = true;
- }
- }
- };
- // 调用
- EventUtil.addHandler(ele, 'click', handler);
- EventUtil.removeHandler(ele, 'click', handler);
五, event 事件对象
event | 主流浏览器 event | ie8 以下 window.event |
---|---|---|
事件处理函数正在处理的元素 | event.currentTarget | |
事件发生在的具体元素 | event.target | event.srcElement |
阻止特定事件的默认行为 | event.preventDefault() | event.returnValue = false |
阻止事件冒泡 | event.stopPropagation() | event.cancleBubble = true |
event.eventPhase 判断事件处理函数执行时, 元素处于的阶段
1: 在捕获阶段
2: 在目标对象上
3: 冒泡阶段
event.eventPhase = 2 时, this=event.currentTarget = event.target
六, 事件委托
解决问题: 如果页面上所有需要绑定事件的元素都单个绑定相应的事件处理程序, 1, 那么将会绑定很多单独的程序, 全局内存占用很多, 影响页面性能, 2, 访问 DOM 次数太多, 延迟页面交互就绪时间
原理: 利用事件冒泡, 为顶级页面元素或者模块中最头部元素指定事件处理函数
- html:
- <div id="box">
- <ul id="list">
- <li id="one">1 行 </li>
- <li id="two">2 行 </li>
- <li id="three">3 行 </li>
- </ul>
- </div>
- js:
- var ele = document.getElementById('box');
- EventUtil.addHandler(ele, 'click', function (event) {
- var event = EventUtil.getEvent(event);
- // 获取发生事件的目标元素
- var target = EventUtil.getTarget(event);
- // 获取事件目标元素的 id 选择器名
- var id = target.id;
- // 根据不同的元素做不同的处理
- switch(id) {
- case 'box':
- {
- handler(event);
- }
- break;
- case 'list':
- {
- console.log(target);
- }
- break;
- case 'one':
- {
- target.style.color = 'red';
- }
- break;
- case 'two':
- {
- target.style.color = 'blue';
- }
- break;
- case 'three':
- {
- target.style.color = 'green';
- }
- break;
- default: break;
- }
- });
来源: https://www.cnblogs.com/mengjingmei/p/9404155.html