最新更新時間: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>
參考資料
感謝閱讀,歡迎評論^-^