事件的移除
removeEventListener()
第二个参数需要指定要移除的事件句柄,不能是匿名函数,因为无法识别
想要移除成功,那么三个参数必须跟addEventListener中的三个完全一致
<!DOCTYPE html> <html lang="en"head> Meta charset="UTF-8"title>Document</style> body{ width:100%; height; } input display block margin-bottom10px .active colororange} script src="DomReady.js"></script myReady(function(){ var btn1 = document.querySelector("#btn1); click1(){ alert(hello1~); } btn1.addEventListener(click,click1,false); //移除绑定的事件 btn1.removeEventListener(); }); body> button id="btn1">按钮1button> html>
IE事件流
attachEvent(event,function) event都是on开头的
浏览器兼容性主要就是指IE浏览器的兼容,尤其是低版本IE(IE6-8)
IE不支持事件捕获,默认都是冒泡,所以没有第三个参数
detachEvent() 移除事件
DOM0级 兼容所有浏览器
DOM2级
addEventListener 主要兼容谷歌、火狐、IE9+
attachEvent 主要兼容IE6-8
attachEvent 可以绑定多个事件类型,而且后绑定的先执行
还有一个很逆天的知识点补充,匿名函数中的this指向window
); } click2(){ alert(hello2~); } btn1.attachEvent(onclick先弹出hello2,再弹出hello1 btn1.detachEvent(解除绑定hello1,只弹出hello2 this指向window btn1.attachEvent((){ alert(this===window);true }); }); >
跨浏览器事件处理
EventUtil{ addHandler:(ele,type,handler){ if(ele.addEventListener){ ele.addEventListener(type,handler,1)">); }else (ele.attachEvent){ ele.attachEvent(on+type,handler); }else{ ele[type]handler; } },removeHandler:(ele.removeEventListener){ ele.removeEventListener(type,1)">(ele.detachEvent){ ele.detachEvent(null; } } } btn1document.getElementById(btn1); click我被点击啦!); } EventUtil.addHandler(btn1,click); EventUtil.removeHandler(btn1,click); }); >
事件冒泡与事件捕获
直系亲属树
事件冒泡:当某个元素的点击事件被触发之后,由于冒泡,它的直系亲属树上的元素,只要被添加了事件的,都会被触发(从下往上)
事件捕获:当某个元素的点击事件被触发之后,由于捕获,它的直系亲属树上的元素,只要被添加了事件的,都会被触发(从上往下)
大部分情况下,都是使用事件冒泡
parentparent childchild事件冒泡,先出现child,再出现parent parent.addEventListener(); }); child.addEventListener(); }); 事件捕获,先出现parent,再出现child parent.addEventListener("click",function(){ alert("parent"); },true); child.addEventListener("click",1)"> alert("child"); }); div ="parent"> ="child">点击childdiv>
利用事件冒泡机制实现事件委托
事件绑定会损耗性能,事件委托是一个很棒棒的选择
ulul 父 ul 绑定事件 子 li 没有事件 当子元素(li)被点击时,在子元素直系亲属树上的所有元素,凡是绑定了事件的(ul)都会被触发 ul.addEventListener((event){ event,target可以获取到点击的那个元素 console.log(event.target.innerHTML); (event.target.idli1){ alert(是1哦); }li2是2哦li3是3哦li4是4哦); } }); }); ul ="ul"li ="li1">li1li="li2">li2="li3">li3="li4">li4ul>
w3c 制定的 javascript 标准事件模型,先事件捕获从windows > document 往下级直到 特定的事件节点,然后进行事件处理,再事件冒泡,从特定节点往上级,这个完整的过程。
事件捕获->事件处理->事件冒泡
事件句柄的参数event对象
event.type 事件类型
event.target 被点击的元素
event.currentTarget 被绑定事件的元素
event.preventDefault() 阻止默认行为
event.stopPropagation() 阻止事件捕获或者冒泡,需要添加到子元素上
clientY 浏览器顶部底边到鼠标的位置
pageY 浏览器顶部底边到鼠标的位置+页面滚动的距离
screenY 屏幕顶部到鼠标的位置(如果浏览器缩小,screenY依然是根据电脑屏幕来计算,与浏览器无关)
#scroll1000px background#abcdef); ul.addEventListener((event){ console.log(event.type);click console.log(event.target);<li id="li3">li3</li> console.log(event.currentTarget); /* <ul id="ul"> <li id="li1">li1</li> <li id="li2">li2</li> <li id="li3">li3</li> <li id="li4">li4</li> </ul> */ alert(event.target.innerHTML); }); aa); a.addEventListener((event){ event.preventDefault();阻止了a链接的跳转 alert(hello); }) 阻止子元素执行时冒泡到父元素 ); parent.addEventListener((event){ alert(); event.stopPropagation(); }); child.addEventListener(); event.stopPropagation(); }); scrollscroll); scroll.addEventListener((event){ console.log(event.pageY);813 console.log(event.clientY);480 console.log(event.screenY);535 }) }); a ="a" href="http://www.baidu.com">点击链接a>这是儿子="scroll">这是滚动区域>
IE中的event对象(attachEvent)
event.type 事件类型
event.returnValue=false; 阻止默认行为
event.cancelBubble=true; 阻止冒泡,需要添加到子元素上
event.srcElement 被点击的元素
); ul.attachEvent((event){ alert(event.type);click alert(event.srcElement.innerHTML);点击li1,弹出li1 }); ); a.attachEvent(阻止默认行为 event.returnValue; alert(阻止子元素执行时冒泡到父元素,需要添加到子元素上 ); parent.attachEvent(); }); child.attachEvent(); event.cancelBubbletrue; }); }); >
Event跨浏览器的兼容性写法
; } },mycurrentTarget:(event){ return event.Target || event.srcElement; },mypreventDefault:(event.preventDefault()){ event.preventDefault(); }{ event.returnValue(event.stopPropagation){ event.stopPropagation(); }{ event.cancelBubble; } } } ); EventUtil.addHandler(a,1)">); EventUtil.mypreventDefault(event); }); ); EventUtil.addHandler(parent,1)">); EventUtil.addHandler(child,1)"> targetEventUtil.mycurrentTarget(event); alert(target.id);<div id="child">这是儿子</div> EventUtil.mystopPropagation(event);阻止冒泡到父元素 }) }); >
UI事件 load
window的load事件
img的load事件
script的load事件
css的load事件
window的unload事件 用户从一个页面切换到另一个页面
window的resize事件 窗口大小调整
window的scroll事件 窗口滚动
由于resize和scroll是重复执行的,因此特别损耗性能
2000px} ; } } } window的load事件 EventUtil.addHandler(window,1)">load(){ alert("window的load事件!"); img图片加载完毕 imgdocument.createElement(img); EventUtil.addHandler(img,1)">alert("img图片加载完毕!"); }); img.srcsource/cat.jpg; img图片预加载(存入内存中) new Image(); EventUtil.addHandler(img,1)">alert("img图片预加载完毕!"); 动态加载js scriptscript); EventUtil.addHandler(script,1)">alert("js加载完毕!"); }); script.srcjquery.js; document.body.appendChild(script); 动态加载css linklink); link.typetext/css; link.relstylesheet; EventUtil.addHandler(link,1)">alert("css加载完毕!"); }); link.hrefstyle.cssdocument.getElementsByTagName[0].appendChild(link); window unload unloadalert("unload!"); window resize resizealert("resize"); window scroll alert("scroll"); }); }); >
焦点事件
onfocus 得到焦点
onblur 失去焦点
鼠标事件
onclick 鼠标单击
ondblclick 鼠标双击
onmousedown 鼠标按下
onmousemove 鼠标在目标区域移动(重复执行影响性能)
onmouseup 鼠标松开
mousedown+mouseup=click
onmouSEOver 鼠标移入(进入元素或者元素的子元素)
onmouSEOut 鼠标移出 (移出元素或者元素的子元素)
onmouseenter 鼠标移入(进入元素本身)
onmouseleave 鼠标移出(移出元素本身)
#div200px margin50px auto position relative #child80pxpink font-size14px absolute left50% top margin-left-40px margin-top line-height text-align center获得焦点 inouttext); EventUtil.addHandler(inout,1)">focusconsole.log("获得焦点"); 失去焦点 blurconsole.log("失去焦点"); 鼠标单击 divdiv); EventUtil.addHandler(div,1)">console.log("鼠标单击"); 鼠标双击 dblclickconsole.log("鼠标双击"); 鼠标按下 mousedownconsole.log("鼠标按下"); 鼠标松开 mouseupconsole.log("鼠标松开"); 鼠标移动 mousemoveconsole.log("鼠标移动"); 鼠标进入 mouSEOver(){ console.log(mouSEOver鼠标进入鼠标离开 mouSEOutmouSEOut鼠标离开mouseentermouseenter鼠标进入mouseleavemouseleave鼠标离开); }); }); input type="text" id value="text"="div">这是子元素>
event.shiftKey shift+点击
event.ctrlKey ctrl+点击
event.altKey alt+点击
#Box} BoxBox); EventUtil.addHandler(Box,1)">(e){ keys[]; (e.shiftKey){ keys.push(shift); } (e.ctrlKey){ keys.push(ctrl(e.altKey){ keys.push(alt(e.MetaKey){ keys.push(Meta); } console.log(keys.join());数组转字符串 ="Box">
针对mousedown,存在event.button
高级浏览器:
event.button=0 鼠标左键
event.button=1 鼠标中键
event.button=2 鼠标右键
IE8及以下:
event.button=0 没有按下鼠标
event.button=1 按下左键
event.button=2 按下右键
event.button=3 同时按下左右键
event.button=4 按下中间键
(e){ console.log(e.button); }); }); >
键盘事件
keydown 按下任意键 keyup 松开键盘 event.keyCode 键码(通过keydown获取)
keypress 按下键盘上的字符键 charCode ascii码(通过keypress获取)
textInput 文本输入 data 输入的文本
(typeof event.charCode == number){ event.charCode; }{ event.keyCode; } } } inputinput); EventUtil.addHandler(input,1)">keydownconsole.log(e.keyCode+"keydown"); }); EventUtil.addHandler(input,1)">keyupconsole.log(e.keyCode+"keyup"); keypressconsole.log(e.charCode+"keypress"); textInput(e){ console.log(e.data="input">
DOM 相关事件
DOMNodeRemoved DOM中某元素被删除
DOMNodeRemovedFromDocument 从文档中被删除前触发(事件句柄必须加在被操作的元素上,浏览器支持性不好,不推荐)
DOMNodeInserted DOM中某元素被添加
DOMNodeInsertedIntoDocument 从文档中被添加之前触发(事件句柄必须加在被操作的元素上,浏览器支持性不好,不推荐)
DOMSubtreeModified DOM结构发生改变
DOMContentLoaded DOM树加载完即可
loaded DOM树加载完,并且图像+js+css等其他资源也加载完
因此DOMContentLoaded速度快于loaded
hashchange #后面的值发生变化,只能给window对象绑定
event.oldURL 原来的url
event.newURL 新的url
DOM中某元素被删除 EventUtil.addHandler(document,1)">DOMNodeRemovedconsole.log("removed");//removed }); ul.removeChild(ul.children[3]); DOM中某元素被添加 lili); EventUtil.addHandler(document,1)">DOMNodeInsertedconsole.log("inserted");//inserted ul.appendChild(li); DOM结构从文档中被删除之前触发 addHandler中填写的是被删除的元素 ul.children[3]; EventUtil.addHandler(li,1)">DOMNodeRemovedFromDocumentconsole.log("DOM结构从文档中被删除之前触发");//DOM结构从文档中被删除之前触发 ul.removeChild(li); DOM结构从文档中被添加之前触发 addHandler中填写的是被添加的元素 ); EventUtil.addHandler(li,1)">DOMNodeInsertedIntoDocumentconsole.log("DOM结构从文档中被添加之前触发");//DOM结构从文档中被添加之前触发 ul.appendChild(li); DOM结构发生改变 DOMSubtreeModifiedconsole.log("DOM结构发生改变");//DOM结构发生改变 ul.removeChild(ul.children[3]);//4被删除 ul.removeChild(ul.children[3]);//4被删除 DOM树加载完 DOMContentLoadedconsole.log("DOM树加载完");//DOM结构发生改变 hash值改变 hashchange(e){ console.log(e.oldURL + \n" e.newURL);DOM结构发生改变 file:///C:/Users/96579/Desktop/index.html#11 file:///C:/Users/96579/Desktop/index.html# }); }); >1>2>3>4>
移动端常用事件 类型
touchstart 手指接触屏幕
touchmove 手指在屏幕上移动
touchend 手指离开屏幕
touchcancel 系统停止触摸跟踪时触发
首先在head上添加移动端适配的设置:
<Meta name="viewport" content="width=device-width,initial-scale=1.0">
touch的event对象
event.touches 屏幕上的触摸点个数
event.changedTouches 屏幕上移动的触摸点的个数
event.targetTouches 目标区域内的触摸点的个数
name="viewport" content="width=device-width,initial-scale=1.0"100px); EventUtil.addHandler(div,1)">touchstart(e){ console.log(); console.log(e.touches); console.log(e.changedTouches); console.log(e.targetTouches); }); EventUtil.addHandler(div,1)">touchmove); }); EventUtil.addHandler(div,1)">touchend); }); }); >
一个小案例:
400px border1px solid50px #ul list-style none #ul li30px border-radius5px inline-block cursorpointer #ul li:hover#fff #ul li:first-child #ul li:nth-child(2) #ul li:nth-child(3)lightgreen #ul li:last-child); EventUtil.addHandler(ul,1)"> eevent.target;缓存 (e.innerHTML==仙女粉){ div.style.background; }气质蓝薄荷绿元气橙; } }); }); >仙女粉>气质蓝>薄荷绿>元气橙>