事件对象是什么?
事件对象表示事件的状态。由浏览器创建,具有鼠标位置坐标,事件元素位置坐标,元素事件是否冒泡等。
获取事件对象
当事件触发时,事件对象会作为参数传递给事件响应函数。我们定义一个形参就可以获得事件对象(使用arguments也可以获取)。即使不写形参,在事件响应函数中也可以直接使用event获取事件对象(亲测Edge,谷歌,火狐可以)。
div.onclick=function(){console.log(event); console.log("box响应点击");}
IE浏览器即将退役,在此不再写兼容IE浏览器需要的获取事件方式。如有兴趣可以自行了解。
事件对象的属性和方法
属性
event.target 返回触发事件的对象。与this不同,this指向绑定事件的对象。
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试</title>
<style>
#box{
width:200px;
height: 200px;
background-color: #ccc;
}
#son{
width: 150px;
height: 150px;
background-color: #0f0;
}
#inner{
width: 100px;
height: 100px;
background-color: #0ff;
}
</style>
</head>
<body>
<div id="box">
<div id="son">
<div id="inner"></div>
</div>
</div>
<script>
var box=document.getElementById("box");
box.onclick=function(){
console.log(event.target);
console.log(this);
}
</script>
</body>
</html>
当点击最小元素时,可以通过输出内容看出两者的差别。前者是id为inner的元素,后者是id为box的元素。
event,srcElement 上一个属性的非标准别称。可以理解为ie浏览器的event.target。虽然其他浏览器也支持这个属性,但应避免使用这个非标准属性(说不定哪一天就废弃了)。
event.type 返回事件的类型。只读。eg:click事件会返回click。
event.currentTarget 指向绑定事件的元素,效果和this一样(能使用this也可以使用这个属性)。老版本的ie不兼容。
event.cancelable 返回一个布尔值,指定事件是否可以取消。可以取消返回true,反之返回false。
针对点击,提交等操作一般可以取消。我们可以使用事件的preventDefault方法来取消事件。
var box=document.getElementById("box");
box.onclick=function(){
console.log(event.cancelable);
}
click事件就是可以取消的。输出值为true。
event.cancelBubble 可修改的布尔值。将这个属性设置为true可以阻止事件冒泡传递和捕获传递。也可以理解为阻止事件传递。
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试</title>
<style>
#box{
width:200px;
height: 200px;
background-color: #ccc;
}
#son{
width: 150px;
height: 150px;
background-color: #0f0;
}
#inner{
width: 100px;
height: 100px;
background-color: #0ff;
}
</style>
</head>
<body>
<div id="box">
<div id="son">
<div id="inner"></div>
</div>
</div>
<script>
var box=document.getElementById("box");
var son=box.children[0];
var inner=son.children[0];
// box.onclick=function(){
// console.log("box响应点击");
// }
// son.onclick=function(){
// console.log("son响应点击");
// }
// inner.onclick=function(){
// event.cancelBubble=true;
// console.log("inner响应点击");
// }
box.addEventListener("click",function(){event.cancelBubble=true;console.log("box响应点击")},true);
son.addEventListener("click",function(){console.log("son响应点击")},true);
inner.addEventListener("click",function(){console.log("inner响应点击")},true)
</script>
</body>
</html>
这里点击内部的inner 事件就不会再传递到其他元素。不论是冒泡还是捕获传递。
event.bubbles 返回一个布尔值,说明该事件是否可以冒泡。例如onclick返回真,onmouseenter返回假。这个属性与是否使用addEventListener中的捕获传递无关。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试网页</title>
</head>
<body>
<p>点击按钮查看 onclick 事件是否为冒泡事件。</p>
<button>试一试</button>
<script>
var btn=document.getElementsByTagName("button")[0];
// btn.addEventListener("mouseenter",function(){alert(event.bubbles);},true);//输出为假
// btn.addEventListener("click",function(){console.log(event.bubbles)},false);//输出为真
</script>
</body>
</html>
event.defaultPrevented 返回一个布尔值,表示该事件对象是否调用了preventDefault()方法。
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试</title>
<style>
#box{
width:200px;
height: 200px;
background-color: #ccc;
}
</style>
</head>
<body>
<div id="box">
</div>
<input type="text" name="" id="">
<script>
var box=document.getElementById("box");
var btn=box.nextElementSibling;
box.addEventListener("click",function(){
if(btn.value!=""){
event.preventDefault();
}
console.log(event.defaultPrevented);
console.log("box响应点击");
box.style.backgroundColor="rgb("+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+")";
},true);
</script>
</body>
</html>
实例中如果输入不为空字符串,就会启用preventDefault方法。而后就会输出defaultPrevent的值。事件函数实现了点击切换一个随机背景颜色的效果。
event.istrusted 返回一个布尔值,表示事件是否可信。 (使用范围并不广泛)
当事件是由用户创建的时,返回值为true(当然信任开发者了)。当事件是由脚本创建,修改,通过dispatchEvent派发时,返回值为false。
event.eventPhase 表示事件流当前处于哪一阶段。更多细节可到
图片来自MDN
event.returnValue 返回一个布尔值。表示事件的默认操作是否被阻止。一般为true。设置为false时可以起到阻止默认操作的作用。
a.onclick=function(){
event.returnValue=false;//不会进行页面跳转
}
也可以使用preventDefault方法阻止,然后输出这个属性检测效果。
var box=document.getElementById("box");
var a=box.children[0];
// box.addEventListener("click",function(){
// // event.preventDefault()//该语句调用就会阻止默认行为,阻止后下面的returnValue就为false
// console.log(event.returnValue);//不调用上面语句这里会输出true
// },true);
event.timeStamp 返回事件发生时的时间戳(从文档加载到事件触发的毫秒数)。
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试</title>
<style>
#box{
width:200px;
height: 200px;
background-color: #ccc;
}
</style>
</head>
<body>
<div id="box">
<a href="www.baidu.com">百度</a>
</div>
<script>
window.onload=function(){
console.log(event.timeStamp);
}
var box=document.getElementById("box");
var a=box.children[0];
a.onclick=function(){
event.returnValue=false;
console.log(event.timeStamp);
}
</script>
</body>
</html>
event.composed 返回一个布尔值,指定该事件是否可以从shadowDOM传递到一般的DOM
方法
event.preventDefault() 无参数,返回值为undefined。如果当前的默认事件可以阻止,该方法调用后就会阻止该默认事件发生。但是不影响这个事件的传递就是了。例如针对于超链接的阻止跳转。
a.onclick=function(){
event.preventDefault();
console.log(event.timeStamp);
}
阻止了默认事件的发生,但是不影响事件函数的触发。还是会输出时间戳,但是不会跳转页面。
event.stopImmediatePropagation() 使用该方法后,同一类型的其他事件监听器就不会执行,并且该方法也可以阻止事件的传递。
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试</title>
<style>
#box{
width:200px;
height: 200px;
background-color: #ccc;
}
</style>
</head>
<body>
<div id="box">
</div>
<script>
var box=document.getElementById("box");
box.addEventListener("click",function(){
console.log("第一个执行");
},false);
box.addEventListener("click",function(){
// event.stopImmediatePropagation();//不执行这一句的话就会顺序执行三个事件响应函数
// 再执行document的点击函数
console.log("第二个执行");
},false);
box.addEventListener("click",function(){
console.log("第三个执行");
},false);
document.addEventListener("click",function(){
console.log("domcument的响应函数");
})
</script>
</body>
</html>
event.stopPropagation() 该方法阻止事件的传递,不管是冒泡传递还是捕获传递都会阻止。
//获取元素部分
var box=document.getElementById("box");
var son=box.children[0];
var inner=son.children[0];
//绑定事件函数
// box.onclick=function(){console.log("box响应点击");}
// son.onclick=function(){console.log("son响应点击");}
// inner.onclick=function(){console.log("inner响应点击");}
box.addEventListener("click",function(event){event.stopPropagation();console.log("box响应点击");},true);
son.addEventListener("click",function(){console.log("son响应点击");},true);
inner.addEventListener("click",function(){console.log("inner响应点击");},true);
这时阻止了事件进一步向下传递(向内部传递)。这里展示的是阻止捕获。
这个方法也可以阻止事件冒泡。与上面不同的是需要将stopPropagation在内层的元素事件中使用。
//获取元素部分
var box=document.getElementById("box");
var son=box.children[0];
var inner=son.children[0];
//绑定事件函数
box.onclick=function(){console.log("box响应点击");}
son.onclick=function(){console.log("son响应点击");}
inner.onclick=function(){event.stopPropagation();console.log("inner响应点击");}
这里在冒泡传递的情况下,由inner元素向上传递事件,在起始的位置就被stopPropagation方法阻止冒泡。即使点击内层元素也只有一个元素响应事件。
event.composedPath() 方法,详细可见 。
以上就是本次学习内容的分享,本文参考MDN
部分废弃方法属性没有涉及(应该也不会再回来了),部分属性方法使用频率低或不太好用,没有大篇幅展开叙述。
本文如有错误或不足之处,欢迎指正。