一、基本概念
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; ???}});
JS事件程序处理
原文地址:https://www.cnblogs.com/mengjingmei/p/9404155.html