1.如何注冊事件(如何綁定事件)
? 何為注冊事件,就是給元素添加事件,其方式有傳統注冊事件、方法監聽注冊事件。
-
0、1級事件(傳統注冊事件)不允許多個響應程序
我們在元素內或js內使用on的方式就是傳統注冊事件,這種形式添加的事件叫DOM 0級事件(DOM L0 事件),如onclick、onblur等
<div id="box" onclick="fn()"></div> <script> // js里面也可以注冊事件let box = document.getElementById("box")box.onclick = function (){console.log("注冊click事件成功1") }box.onclick = function (){console.log("注冊click事件成功2") }//這里只會打印"注冊click事件成功2" ,因為不允許多個響應程序,后面會覆蓋前面的事件 </script>
-
2級事件(方法監聽注冊事件)允許多個響應程序,事件觸發時依次調用
-
方法1:元素.addEventListener:
// IE9之前的IE不支持此方法 元素.addEventListener('事件名', 事件響應程序(函數)callback,useCapture) // useCapture:可選參數,是一個布爾值,默認是 false // true 是捕獲階段 false是冒泡階段 事件觸發會依據事件流的順序調用 // 例如以下 box.addEventListener('click', function () {// 給box添加點擊事件 }) // 允許多個響應程序,事件觸發時依次調用 box.addEventListener('click', function () {console.log('1') }) box.addEventListener('click', function () {console.log('2') })//這里會依次打印1、2
-
方法2:元素.attachEvent( on事件名, 響應程序 )
// IE9之前的瀏覽器支持 元素.attachEvent( on事件名, 事件響應程序(函數)callback ) box.attachEvent('onclick', function () {})
2.如何刪除事件(如何解除綁定事件)
用哪種方式添加的事件,我們只能用對應方式來刪除,無法混用,而且要注意是否注冊的是匿名函數,這種事件無法刪除。
-
0、1級事件的刪除方法:
元素.on事件名 = null 或者 = undefined box.onclick = null 或者 box.onclick = undefined
-
2級事件的刪除方法:
addEventListener的刪除:
元素.removeEventListener('事件名', 函數名) // 匿名函數例子 box.addEventListener('click', function () {console.log('1') }) // 非匿名 function fn(){} box.addEventListener('click', fn) // 刪除例子 box.removeEventListener('click',fn)
attachEvent的刪除
元素.detachEvent('on事件名', 函數名)
3.什么是DOM事件流
-
事件流:當一個事件觸發后,它其實經歷了從上(捕獲階段)到下(事件目標),又從下(事件目標)到上(冒泡階段)的流動過程,這就稱之為事件流
-
事件冒泡默認存在的,事件捕獲要寫特殊代碼才能看到,如下。
- 例如:addEventListener的第三個參數寫為true就是事件捕獲,所以前面寫的addEventListener里面提到的就是這里
-
不管是捕獲、冒泡,都會觸發同名事件
-
事件流如果不寫特殊代碼,會經歷完整的事件流。
<div id="div1" style="background: blue;width: 100px; height: 100px;"><div id="div2" style="background: red;width: 70px; height: 70px;"><div id="div3" style="background: yellow;width: 50px; height: 50px;"></div></div> </div> <script type="text/javascript">var oDiv1 = document.getElementById('div1'),oDiv2 = document.getElementById('div2'),oDiv3 = document.getElementById('div3');oDiv1.addEventListener('click', showBlue, true); oDiv2.addEventListener('click', showRed, false); oDiv3.addEventListener('click', showYellow, true); function showBlue(){ //藍 alert("blue");} function showRed(){ //紅 alert("red"); } function showYellow(){//黃 alert("yellow");}// 結果“blue”,“yellow”,“red” // true 是捕獲階段,依據事件流是先執行,所以先出藍 黃,false是冒泡階段,所以最后出紅 </script>
-
4.什么是事件對象
? 事件對象也是一個對象,里面保存了事件觸發時的相關信息,event 對象代表事件的狀態,比如鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。
比如:鍵盤觸發的事件,會得到鍵盤相關信息,如enter鍵
-
怎么獲取事件對象?
- 如事件綁定的函數里寫一個形參event/e、或者寫window.event
-
事件對象的兼容性方案(IE6~8 和IE8之后都可以使用)?
- e = e || window.event
eventTarget.onclick = function(event) { // 這個 event 就是事件對象} eventTarget.addEventListener('click', function(event) { }) // 形參是可變的,隨便起名字,但一般用event、e、ev
-
怎么獲取事件源?
事件對象.target || e.target
是我們事件觸發的元素,比如我點body就是body,我點div就點的那個div;this
當前事件調用函數的綁定元素,this是注冊當前事件的父元素;
事件對象常見的屬性方法 | 說明 |
---|---|
e.targer | 返回觸發事件的對象 標準 |
e.type | 返回事件的類型 比如click mouseover 不帶on |
e.cancelBubble | 該屬性阻止冒泡 非標準 ie6-8使用 |
e.returnValue | 該屬性阻止默認事件(默認行為) 非標準 ie6-8使用 比如不讓鏈接跳轉 |
e.preventDafault() 阻止事件默認行為 | 該方法阻止默認事件(默認行為) 標準 比如不讓(a標簽)鏈接跳轉 |
e.stopPropagation() | 阻止冒泡標準,當父子有同名事件,為了不相互影響時可以使用 |
e.currentTarget | 與this一樣,非標準 ie6-8使用 |
5.阻止事件冒泡、事件捕獲(阻止事件流)
- e.stopPropagation() (IE9后支持)
- 可以阻止冒泡、捕獲階段
- e.cancelBubble = true(IE9前支持)
- IE9之前沒有事件捕獲(因為IE9之前無法用addEventListener)
// 兼容性解決方案box.addEventListener('click', function(e) {alert('box');
// 兼容性寫法
if (e && e.stopPropagation) {e.stopPropagation(); //適用于ie9后
} else {window.event.cancelBubble = true; // 適用于ie678
}
}, false);
工作實際案例場景:1、登錄頁面,登錄彈出框與后面父元素背景的點擊事件沖突時;2、移動端,某個彈出框,不希望點擊到陰影部分的功能;3、拓撲頁面存在點擊事件,需要在上層彈出某個彈框,可以拖拽改變頁面大小;
6.事件委托(事件代理、事件委派)
? 把給每個子元素單獨設置事件監聽器的需求,改成事件監聽器設置在其父元素上,利用冒泡原理代理到子元素上。
-
好處:減少綁定事件的次數,提高性能(只操作了一次 DOM ,提高了程序的性能),減少代碼冗余,即使新增的子元素也享有事件監聽器;
-
需求:給li添加點擊事件,并且獲得里面的key值
解決辦法1:給每個li添加點擊事件,這種方法代碼太過冗余
優化解決辦法:把事件委托給ul元素,給它添加點擊事件方法,利用事件冒泡
-
<ul><li key="1">點我點我寶貝</li><li key="2">點我點我寶貝</li><li key="3">點我點我寶貝</li><li key="4">點我點我寶貝</li><li key="5">點我點我寶貝</li><span key="6">不是li</span><span key="7">不是li</span> </ul> <script>let ul = document.querySelector('ul');ul.addEventListener('click',function(e){if(e.target.tagName === 'LI'){ // 判斷是不是li標簽return e.target.getAttribute('key')}}) </script>
7.常用的事件
①鼠標事件
鼠標事件 | 觸發條件 |
---|---|
onclick | 鼠標點擊左鍵觸發 |
onmouseover | 鼠標經過觸發 |
onmouseout | 鼠標離開觸發 |
onfocus | 獲取鼠標焦點觸發 |
onblur | 失去鼠標焦點觸發 |
onmousemove | 鼠標移動觸發 |
onmouseup | 鼠標彈起觸發 |
onmousedown | 鼠標按下觸發 |
contextmenu | 鼠標右鍵觸發(e.preventDefault() 阻止彈出右鍵菜單,場景:取消默認的上下文菜單,加入自己的菜單;復制網頁內容功能屏蔽) |
selectstart | 鼠標選擇開始(e.preventDefault() ;場景:復制網頁內容功能屏蔽,禁止用戶選中) |
MouseEvent鼠標事件對象 | 說明(像素距離) |
---|---|
e.clientX | 鼠標相對于瀏覽器窗口可視區的X坐標(變) |
e.clientY | 鼠標相對于瀏覽器窗口可視區的Y坐標(變) |
e.pageX | 鼠標相對于頁面的X坐標 IE9+支持(doc) |
e.pageY | 鼠標相對于頁面的Y坐標 IE9+支持(doc) |
e.screenX | 鼠標相對于電腦屏幕的X坐標 |
e.screenY | 鼠標相對于電腦屏幕的Y坐標 |
②鍵盤事件
使用addEventListener 不需要加 on
鍵盤事件 | 觸發條件 |
---|---|
onkeydown/keydown | 按下時觸發,不區分大小寫字母,任何鍵 |
onkeyup/keyup | 松開時觸發,不區分大小寫字母,任何鍵 |
onkeypress/keypress | 按下時觸發,介于 keydown 和 keyup之間,(a-z0-9回車和空格),會區分大小寫,不識別功能鍵 |
鍵盤事件對象 | 說明 |
---|---|
keyCode | 返回該鍵的ASCII值 |