最新更新时间:2020年05月27日10:57:02
《猛戳-查看我的博客地图-总有你意想不到的惊喜》
本文内容:Event对象的一些知识点,事件注册、事件对象、阻止事件
概述
Event 接口表示在 DOM 中发生的任何事件; 一些是用户生成的(例如鼠标或键盘事件),而其他由 API 生成(例如指示动画已经完成运行的事件,视频已被暂停等等)。
为DOM元素注册事件处理函数的三种方式
- 方式一:EventTarget.addEventListener
myButton.addEventListener('click', function(){alert('Hello world');}, false);
- 方式二:HTML 属性
<button onclick="alert('Hello world!')">
- 方式三:DOM 元素属性
myButton.onclick = function(event){alert('Hello world');};
三种方式的实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="div" onclick="htmlAttr()">123</div>
</body>
<script>
functionhtmlAttr(){
console.log(1);
}
let div = document.getElementById('div')
div.addEventListener('click', function(){console.log(2);}, false);
div.onclick = function(event){console.log(3);};
</script>
</html>
输出的结果:3 2
let div = document.getElementById('div')
div.addEventListener('click', function(){console.log(2);}, false);
div.onclick = function(event){console.log(3);};
function htmlAttr(){
console.log(1);
}
输出的结果:3 2
functionhtmlAttr(){
console.log(1);
}
let div = document.getElementById('div')
div.addEventListener('click', function(){console.log(2);}, false);
输出的结果:1 2
let div = document.getElementById('div')
div.addEventListener('click', function(){console.log(2);}, false);
functionhtmlAttr(){
console.log(1);
}
输出的结果:1 2
- 总结:方式三可以覆盖方式二,方式一最晚执行
DOM Event 接口中阻止事件执行的三个方法
- event.preventDefault
取消事件(如果该事件可取消)。阻止默认行为,比如:页面滚动、复选框选中、在文本编辑域中阻止有效的文本输入
使用 Event.cancelable 来检查该事件是否支持取消。为一个不支持cancelable的事件调用preventDefault()将没有效果。
- event.stopImmediatePropagation
场景一:同一DOM元素上相同的多个事件按照先后顺序执行的行为被终止。
如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果其中某个监听函数执行了 event.stopImmediatePropagation() 方法,则当前元素剩下的监听函数将不会被执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="sup">
<div id="sub">123</div>
</div>
</body>
<script>
let sub = document.getElementById('sub')
sub.addEventListener('click', function(e){
e.stopImmediatePropagation()
console.log(3);
}, false);
sub.addEventListener('click', function(e){
console.log(4);
}, false);
</script>
</html>
输出的结果:3
场景二:阻止事件冒泡,祖先元素上的相同事件不会执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="sup" onclick="htmlAttr()">
<div id="sub">123</div>
</div>
</body>
<script>
function htmlAttr(){
console.log(1);
}
let sup = document.getElementById('sup')
let sub = document.getElementById('sub')
sup.addEventListener('click', function(){console.log(2);}, false);
sub.addEventListener('click', function(e){
e.stopImmediatePropagation()
console.log(3);
}, false);
</script>
</html>
输出的结果:3
对这个特定的事件而言,没有其他监听器被调用。这个事件既不会添加到相同的元素上,也不会添加到以后将要遍历的元素上(例如在捕获阶段)。
- event.stopPropagation
只包含event.stopImmediatePropagation中的场景二。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="sup" onclick="htmlAttr()">
<div id="sub">123</div>
</div>
</body>
<script>
function htmlAttr(){
console.log(1);
}
let sup = document.getElementById('sup')
let sub = document.getElementById('sub')
sup.addEventListener('click', function(){console.log(2);}, false);
sub.addEventListener('click', function(e){
e.stopPropagation()
console.log(3);
}, false);
sub.addEventListener('click', function(e){
console.log(4);
}, false);
</script>
</html>
输出的结果:3 4
event.preventDefault
应用场景
- 当移动一个可拖动元素(比如悬浮球)时,需要阻止页面滚动
onTouchStart(e){
let _this = this;
document.body.addEventListener('touchmove', _this.preventScroll, {passive: false});//passive 参数不能省略,用来兼容ios和android
}
onTouchEnd(e){
let _this = this;
document.body.removeEventListener('touchmove', _this.preventScroll);
}
preventScroll(e){
e.preventDefault();//阻止页面滚动
}
render(){
return <div
onTouchStart={(e)=>{this.onTouchStart(e)}}
onTouchMove={(e)=>{this.onTouchMove(e)}}
onTouchEnd={(e)=>{this.onTouchEnd(e)}}
></div>
}
event.stopImmediatePropagation
应用场景
- react中阻止事件监听器冒泡:页面中的图片位置和数量不定,当用户点击图片时需要进行放大预览,如果图片的祖先元素绑定了click事件,此时不需要触发
let _this = this;
document.addEventListener('click',function(e){
let dom = e.target;
let src = e.target.getAttribute('src');
//可以进行预览的图片域名为wansahobo
if(dom.tagName.toLowerCase() == 'img' && src.indexOf('wanshaobo') > -1){
e.stopImmediatePropagation();//阻止祖先元素的click事件触发
_this.previewImg(src);//放大预览
}
},false);
event.stopPropagation
应用场景
- 阻止祖先元素上方式一和方式二的相同类型注册事件,但不能阻止方式三
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="sup" onclick="htmlAttr()">
<div id="sub">123</div>
</div>
</body>
<script>
function htmlAttr(){
console.log(1);
}
let sup = document.getElementById('sup')
let sub = document.getElementById('sub')
sup.addEventListener('click', function(){console.log(2);}, false);
sub.addEventListener('click', function(e){
e.stopPropagation()
console.log(3);
}, false);
sub.addEventListener('click', function(e){
console.log(4);
}, false);
sup.onclick = function(event){console.log(5);};
</script>
</html>
输出的结果:3 4 5
横向对比
- 在事件注册方式一
EventTarget.addEventListener
中,横向对比三种阻止事件的方法
- | preventDefault | stopImmediatePropagation | stopPropagation |
---|---|---|---|
阻止祖先元素上的事件绑定方式一 | 否 | 是 | 是 |
阻止祖先元素上的事件绑定方式二 | 否 | 是 | 是 |
阻止祖先元素上的事件绑定方式三 | 否 | 是 | 否 |
阻止元素自身的事件绑定方式一 | 否 | 是 | 否 |
阻止元素自身的事件绑定方式二 | 否 | 是 | 是 |
阻止元素自身的事件绑定方式三 | 否 | 是 | 否 |
阻止浏览器默认行为 | 是 | 否 | 否 |
event对象实例
clickDiv(e){
console.log(e.target);//被点击的元素
console.log(e.currentTarget);//绑定该事件的元素
}
render(){
return <div onClick={(e)=>{this.clickDiv(e)}}></div>
}
Demo源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<!-- 2 -->
<div id="sup" onclick="supC()">
<div id="sub" onclick="subC()">123</div>
</div>
</body>
<script>
let sup = document.getElementById('sup')
function supC(){
console.log(1);
}
sup.onclick = function(event){console.log(2);};
sup.addEventListener('click', function(e){
console.log(3);}, false);
sup.addEventListener('click', function(){
console.log(4);
}, false);
let sub = document.getElementById('sub')
function subC(){
console.log(5);
}
sub.addEventListener('click', function(e){
// e.preventDefault()
// e.stopImmediatePropagation()
// e.stopPropagation()
console.log(6);
}, false);
sub.addEventListener('click', function(e){
console.log(7);
}, false);
sub.onclick = function(event){console.log(8);};
</script>
</html>
参考资料
感谢阅读,欢迎评论^-^