有2个:HTML标签中事件和元素.on事件=函数
<a href="#" onclick="open()">打开a>
var btn = document.getElementById("btn1");
btn.onclick=function(){
console.log("sj1");
}
btn.onclick=function(){ //会覆盖原来的函数
console.log("sj2");
}
这种方法只能触发一个函数,若要触发多个可以用addEventListener
只有一个:addEventListener()
IE 678不支持
addEventListener可以给一个对象添加多个触发函数
//以前只支持
addEventListener(type,listener[,useCapture])
//2017年年底 DOM规范做了修订,第三个参数可以是对象值了
addEventListener(type,listener[,options])
//参数如下,默认都为 false
options{
capture:false, //相等于以前的第三个参数(useCapture)
passive:false, //是否取消检测 preventDefault,详细内容看 "passive详解" 小节
once:false //是否只能触发一次(触发一次后removeEventListener)
}
参数3解析:一个事件触发的流程是 触发事件 -> 捕获过程 -> 冒泡过程
//若都是冒泡阶段触发,则执行顺序为:d3,d2,d1(从里向外冒泡)
d1.addEventListener('click',say);
d2.addEventListener('click',say);
d3.addEventListener('click',say);
//若都是捕获阶段触发,则执行顺序为:d1,d2,d3(从外向里)
d1.addEventListener('click',say,true);
d2.addEventListener('click',say,true);
d3.addEventListener('click',say,true);
混合:
//由内向外依次检测是否有捕获过程执行的,然后冒泡
//若一部分是冒泡,一部分是捕获,则先从外向里执行捕获,再从里向外执行冒泡
d1.addEventListener('click',say,true);
d2.addEventListener('click',say);
d3.addEventListener('click',say);
有:blur、focus、load、unload、onmouseenter、onmouseleave
例:
d1.addEventListener('mouseenter',say);
d2.addEventListener('mouseenter',say);
d3.addEventListener('mouseenter',say);
document.body.addEventListener('mouseenter',say);
document.addEventListener('mouseenter',say);
鼠标移入body,结果为:body
鼠标移入d1,结果为:d1
鼠标移入d2,结果为:d2
…
鼠标直接移入d3,结果为:body,d1,d2,d3
document的事件没有被触发,因为该事件不会冒泡
直接移入d3产生了"类似冒泡",是因为其他元素真实产生了事件,然后按事件捕获由外由内执行
若是click事件,则无论任何时候,都会产生冒泡
总结:不冒泡的事件,例如load时每个元素如果都冒泡的话就没有意义了
IE,谷歌,火狐:event.stopPropagation()
IE,谷歌:event.cancelBubble = true
例:
//点击d3,结果只有d3,没有冒泡到父级
d1.addEventListener('click',say);
d2.addEventListener('click',say);
d3.addEventListener('click',say);
function say(){
//兼容性代码
event=event | window.event;
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
......
}
移动设备上有一个touchmove
事件,在手指滑动屏幕时触发,系统默认事件是根据滑动方向滚动页面
//如下代码,会阻止默认事件,造成页面无法滚动
document.addEventListener("touchmove",function(){
event.preventDefault(); //阻止本次事件
});
//取消检测preventDefault,此时屏幕可以正常滚动
document.addEventListener("touchmove",function(){
event.preventDefault();
},{passive:true}); //不检测 preventDefault,使其失灵
其实passive最大的作用是减少运算,增加页面滚动流畅度(看对比图)
//默认情况下,系统会一直检测preventDefault是否存在,会占用cpu资源
//可以用passive关闭对它的检测,减少运算
document.addEventListener("touchmove",function(){},{passive:true});
/*还可用于:
mousewheel(鼠标滚轮事件)
...
*/
passive=false | passive=true |
---|---|
处理器降频处理效果,实际运行只是流畅度不好 | 纵想丝滑 |
removeEventListener(event,function,<useCapture>);
addEventListener中使用不用加on,DOM 0级事件要加on
事件名 | 解释 |
---|---|
onclick | 单击 |
ondblclick | 双击(不要漏了l) |
onmousedown | 鼠标按下 |
onmouseup | 鼠标松开 |
onmousemove | 每次移动都触发 |
onmouseenter | 当次进入时仅触发一次 |
onmouseleave | 当次离开时仅触发一次 |
onmouseover | 当次进入时触发一次,若触碰到子元素并再次回到该元素(并不出界)时会再次触发 |
onmouseout | 离开,进入子元素,进入子元素并回到当前元素,进入子元素的子元素的子…都会触发 |
oncontextmenu | 在当前元素上右击打开菜单时触发(只要弹出菜单就触发,不是必须右键) |
事件名 | 解释 |
---|---|
onkeydown | 按下任意键(按下不松开会一直触发) |
onkeyup | 松开任意键 |
onkeypress | 按下任意键(按下不松开会一直触发)(和keydown相比,按下altctrlf1-f10等键时keypress不会触发) |
事件名 | 解释 |
---|---|
onload | 一般用于window.onload,页面加载完后执行某些代码 |
onchange | 例如文本框内容改变时触发 |
不同浏览器写法(例如window.event/event)和值(例如button属性)不同,可能存在兼容性问题
在触发一个事件时,会产生一个event对象,如下:
d1.addEventListener('mousedown',say);
function say(){
console.log(event); //产生event对象
}
/*
function say(e){console.log(e);} //ok
function say(e){console.log(event);} //ok
*/
属性名 | 解释 |
---|---|
timeStamp | 触发时间(ms) |
target | 事件源 |
button | 鼠标按键 谷歌,IE9+,火狐(左0 ,中1 ,右2 ) IE678(左1 ,中4 ,右2 ) |
pageX/pageY | 光标在页面中的位置(px),例如页面左上角pageX=0,pageY=0 |
clientX/clientY | 光标在页面中相对于可视区域(滚动条外的区域不算)的位置(px) |
会阻止事件冒泡,所以不推荐
<a href="https://www.baidu.com">跳转a>
var a=document.getElementsByTagName("a")[0];
a.onclick=function(){ //注意只能用oncliK. addEventListener无效
return false; //此时点击标签也不会跳转
};
/*
!注意 return false会阻止事件冒泡,所以父对象不会响应
document.οnclick=function(){
console.log("a的父对象document接收到了冒泡事件");
}
*/
这两个方法/属性不会阻止事件冒泡
a.onclick=function(){
if(event && event.preventDefault){ //IE6789
event.preventDefault();
}else{
window.event.returnValue=false; //IE10+,其他
}
};
仅阻止事件冒泡,当前事件仍然响应
a.onclick=function(){
event.stopPropagation();
};
有一个列表:
<ul id="ul">
<li id="li1">li1</li>
<li id="li2">li2</li>
<li id="li3">li3</li>
</ul>
要实现点击li,输出id,正常情况下要分别添加3个li的事件,实际上可以利用冒泡原理,在父元素ul中添加li的事件来实现
实现代码:
ul.addEventListener('click',say);
function say(){
if(event.target.nodeName.toUpperCase()=="LI"){ //判断事件源节点名是不是LI
console.log(event.target.id); //如果是就输出事件源的id
}
}
点击li,虽然li没添加事件,但冒泡到父元素ul时,父元素运行事件代码
利用事件委托可以节省内存,提高效率