-
什么是事件?
事件是一种通知机制,按照事件类型进行匹配
-
事件侦听对象
div.addEventListener("click",clickHandler);
addEventListener
这个方法并没有对于clickHandler
函数的返回结果做处理,因此clickHandler
使用return
无效可以给同一个元素绑定多个事件函数,多个事件的执行顺序和事件绑定的顺序一致
function clickHandler(e){ return; // 事件函数中不要使用return }
- EventTarget所有继承这个类的类别都可以作为事件侦听对象,DOM
- 侦听对象和抛发对象必须相同,谁侦听,谁抛发
- 侦听事件类型和抛发事件类型必须相同
var div = document.querySelector("div"); div.addEventListener("nihao", nihaoHandler); var evt = new Event("nihao"); evt.num = 10; div.dispatchEvent(evt); function nihaoHandler(e) { // e.type 事件类型 console.log(e, evt); console.log(e === evt); //true }
-
on事件和监听事件的区别
-
onclick
只能针对元素使用;addEventListener
可以针对EventTarget
使用(广泛) - 使用on是不可以完成自定义事件,on语句基本上处理的是系统自带事件
- on事件兼容任何浏览器;
addEventListener
只支持IE8以上浏览器 - on事件同一个事件只能执行一个函数;
addEventListener
可以有多个 - on事件容易写成嵌套函数
- on事件无法区分捕获和冒泡事件
-
-
addEventListener
事件侦听的参数- 第一个参数是事件类型 type
- 第二个参数是事件回调函数
- 第三个参数是是否捕获阶段触发 默认是false(冒泡阶段) true是捕获阶段
div0.addEventListener("click", clickHandler1, true); function clickHandler1(e){ // this就是执行该函数的事件侦听对象, e.currentTarget也是事件侦听对象 // e.target和e.srcElement 就是事件目标对象 console.log("div0:",this,e.currentTarget,e.target,e.srcElement); }
e.currentTarget当事件沿着 DOM 触发时事件的当前目标。它总是指向事件绑定的元素 。
-
e.target触发事件的对象 (某个DOM元素) 的引用。
当事件处理程序在事件的冒泡或捕获阶段被调用时,它与event.currentTarget不同。
-
事件的三个处理过程
捕获阶段(由外向内),目标阶段,冒泡阶段(由内向外)
-
事件冒泡
事件是可以流动的,它在触发时,默认情况下,会将事件向父元素进行传播,导致外层也被依次触发,直到页面的最顶层元素。 事件函数的执行顺序按照事件传播的顺序进行。我们称这种现象叫做: 事件冒泡。
-
阻止事件冒泡
var e = evt || event; // 1. if阻止事件冒泡; if(e.stopPropagation){ // IE8 + 及高级浏览器; e.stopPropagation(); }else{ // 原本兼容IE8 , 目前所有浏览器都兼容; e.cancelBubble = true; } // 2. 三目运算; e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; // 3. try{}catch(e){}
-
删除事件
-
删除事件函数
document.onclick = function(){ alert(1); } document.onclick = null;
-
删除监听函数
function handlerClick(){ alert(1); } btn.addEventListener("click",handlerClick); btn.removeEventListener("click",handlerClick); //如果取出函数,那么每个事件的处理函数是独立的。程序设计更为清晰,能减少程序的耦合;
-
-
事件委托机制
注:通过event.target event.srcElement属性,我们可以找到事件触发的原始对象。
- 委托的好处:把元素触发事件时要执行的动作委托给父元素来执行
- 坏处:事件冒泡给父元素,会导致一些不该触发的事件被触发了
-
将放在li中的监听给父级ul
<ul id="list"> <li>hello</li> <li>hello</li> </ul> var list = document.getElementById("list"); list.onclick = function(evt) { var e = evt || event; var target = e.target || e.sreElement; if (target.nodeName === "LI") { var li = document.createElement("li"); li.innerHTML = "Hello,I'm new Li" list.appendChild(li); } }
- 当前事件的事件源
srcElement是IE下的属性,target是Firefox下的属性;Chorme浏览器同时有这两个属性
function(evt) {
var e = evt || event;
var target = e.target || e.sreElement;
}
-
其他侦听事件
- change(input type=text value发生改变并且失焦; select菜单切换改变时触发 )
- submit reset (针对form表单事件 )
- select(针对input文本或者textArea文本,不是针对select表单 )
- error (当一个资源加载失败时会触发error事件 )
- load(是图片的src地址发生改变时,加载新内容完成后,触发 )
- resize(重置大小 解决window的大小变化 )
- scroll (针对任何有滚动条的容器)
-
向页面中预加载图片
function init() { var img = new Image(); img.addEventListener("load", loadHandler); img.src = "./img/" + num + "-.jpg";//改变src的地址,触发img事件 } function loadHandler(e) { // list.push(this); //不能使用这种方法 list.push(this.cloneNode(false));//参数为false代表浅拷贝 num++; if (num > 79) { console.log("加载完成"); this.removeEventListener("load", loadHandler); list.forEach(function(item) { console.log(item.src); }) return; } this.src = "./img/" + num + "-.jpg"; } console.log(list)
-
封装选择器
function mySelector(parent_ele, selector) { var children = parent_ele.children; var res = []; var firstLetter = selector[0]; if (firstLetter.charCodeAt(0) >= 97 && firstLetter.charCodeAt(0) <= 122) { for (var i = 0; i < children.length; i++) { if (children[i].nodeName.toLowerCase() === selector) { res.push(children[i]); } } } if (firstLetter === "#") { res.push(document.getElementById(selector.slice(1))); } if (firstLetter === ".") { for (var i = 0; i < children.length; i++) { if (!children[i].className) continue; var classlist = []; var index = 0; if (children[i].className.split(" ").indexOf(selector.slice(1)) !== -1) { res.push(children[i]); } } } return res; }