目錄
學習目標
- 能寫出元素註冊事件的兩種方式
- 能夠說出刪除事件的兩種方式
- 能夠說出 DOM 事件流的三個階段
- 能夠利用事件對象完成跟隨鼠標案例
- 能夠封裝阻止冒泡的兼容性函數
- 能夠說出事件委託的原理
- 能夠說出常用的鼠標和鍵盤事件
1. 註冊事件(綁定事件)
1.1 註冊事件概述
給元素添加事件,稱爲註冊事件或者綁定事件 。
註冊事件有兩種方式:傳統方式和方法監聽註冊方式。
傳統註冊方式 | 方法監聽註冊方式 |
---|---|
利用 on 開頭的事件 onclick | W3C 標準 推薦方式 |
<button onclick="alert('hi~')"></button> |
addEventListener()它是一個方法 |
btn.onclick = function(){} | IE9 之前的 IE 不支持此方法,可使用 attachEvent() 代替 |
特點註冊事件的唯一性 | 特點:同一個元素同一個事件可以註冊多個監聽器 |
同一個元素同一個事件只能設置一個註冊函數,最後註冊的處理函數將會覆蓋前面註冊的處理函數 | 按註冊順序依次執行 |
var e = e || window.event; //標準化事件對象
1.2 addEventListener 事件監聽方式
eventTarget.addEventListener(type, listener[, useCapture])
eventTarget.addEventListener() 方法值將指定的監聽器註冊到eventTarget(目標對象) 上,當該對象觸發指定的事件時,就會執行事件處理函數。
該方法接收三個參數:
- type:事件類型字符串,比如click,mouseover,注意這裏不要帶 on
- listener:事件處理函數,事件發生時,會調用該監聽函數
- useCapture:可選參數,是一個布爾值,默認是false,學完DOM事件流後,我們在進一步學
栗子:
<body>
<button>傳統註冊方式</button>
<button>方法監聽註冊事件</button>
<script>
var btns = document.querySelectorAll('button');
// 1. 傳統方式註冊事件
btns[0].onclick = function() {
alert('How are you!');
}
btns[0].onclick = function() {
alert('Welcome to China!');
}
// 2. 事件偵聽註冊事件 addEventListener
// (1) 裏面的事件類型是字符串 必定加引號 而且不帶on
// (2) 同一個元素 同一個事件可以添加多個偵聽器(事件處理程序)
btns[1].addEventListener('click', function() {
alert('Welcome to China!');
})
btns[1].addEventListener('click', function() {
alert('Welcome to xinjiang!');
})
</script>
</body>
1.3 attachEvent(IE9以後的都不支持了)
eventTarget.attachEvent(“onclidk”, function(){})
IE都嫌棄,瞭解一下就行,想要看的查百度吧。。。
2. 刪除事件(解綁事件)
https://blog.csdn.net/weixin_45773503/article/details/106005237
3. DOM事件流
事件發生時會在元素節點之間按照特定的順序傳播,這個傳播過程即 DOM 事件流
注意:
- JS 代碼中只能執行捕獲或者冒泡的一個階段。
- onclick 和 attachEvent 只能得到冒泡階段。
- addEvenListener(type, listener[, useCapture])第三個參數如果是 true, 表示在事件捕獲階段調用事件處理程序;如果是 false(不寫默認就是false),表示事件冒泡階段調用事件處理程序
- 實際開發中我們很少使用事件捕獲,我們更關注事件冒泡
- 有些事件是沒有冒泡的,比如 onblur,onfocus,onmouseover,onmouseleave
- 事件冒泡有時候會帶來麻煩,有時候又會幫助很巧妙的做某些事情。
4. 事件對象
事件對象的常見屬性和方法 | 說明 |
---|---|
e.target | 返回觸發事件的類型 標準 |
e.srcElement | 返回觸發事件的對象 非標準 ie6-8使用 |
e.type | 返回事件的類型 比如 click mouseover 不帶 on |
e.cancelBubble | 該事件阻止冒泡 ie6-8使用 |
e.returnValue | 該屬性阻止默認事件(默認行爲)非標準 ie6-8使用 比如不讓鏈接跳轉 屬性 |
e.preventDefault | 該方法 阻止默認事件(默認行爲)標準 比如不讓鏈接跳轉 方法 |
e.stopPropagation | 阻止冒泡 |
<body>
<div>div</div>
<a href="http://www.baidu.com">百度</a>
<form action="http://www.baidu.com">
<input type="submit" value="提交" name="sub">
</form>
<script>
var div = document.querySelector('div');
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn);
div.addEventListener('mouseout', fn);
function fn(e) {
console.log(e.type);
}
// 2. 阻止默認行爲(事件) 讓鏈接不跳轉 或者不讓他提交
var a = document.querySelector('a');
a.addEventListener('click', function(e) {
e.preventDefault();
})
// 3. 傳統的註冊方式
a.onclick = function(e) {
alert('帥');
// 普通瀏覽器 e.preventDefault(); 方法
e.preventDefault();
// 低版本瀏覽器 屬性
e.returnValue;
// 我們可以利用return false 也能阻止默認行爲
return false;
}
</script>
</body>
5. 阻止事件冒泡
5.1阻止事件冒泡的兩種方法
- e.stopPropagation(); 停止冒泡
- e.cancelBubble = ture; 非標準 ie6-8
<body>
<div class="father" style="width: 100px; height: 100px; background-color: antiquewhite;">
<div class="son" style="width: 50px; height: 50px; background-color:red">son</div>
</div>
<script>
var son = document.querySelector('.son');
son.addEventListener('click', function(e) {
alert('son');
// e.stopPropagation(); //停止冒泡
// e.cancelBubble = ture; // 非標準
}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');
}, false);
document.addEventListener('click', function() {
alert('document');
});
</script>
</body>
5.2 阻止事件冒泡的兼容性解決方案
if (e && e.stopPropagation) {
e.stopPropagation();
} else {
window.event.cancelBubble = ture;
}
6. 事件委託(代理,委派)
6.1. 事件委託
事件委託也稱爲事件代理,在jQuery中稱爲事件委派。
6.2. 事件委託的原理
不是每個子節點單獨設置事件監聽器,而是在其父節點上設置事件監聽器,然後利用冒泡來影響設置每個子節點
6.3 事件委託的作用
我們只操作了一次DOM,提高了程序的性能。
6.4 栗子
<body>
<ul>
<li>事件委託</li>
<li>事件委託</li>
<li>事件委託</li>
<li>事件委託</li>
<li>事件委託</li>
</ul>
<script>
var ul = document.querySelector('ul')
var li = ul.children;
console.log(li);
ul.onclick = function(e) {
// alert('I Love China!');
for (var i = 0; i < ul.children.length; i++) {
li[i].style.backgroundColor = '';
}
e.target.style.backgroundColor = "pink";
}
</script>
</body>
7. 常用的鼠標事件
7.1常用的鼠標事件
鼠標事件 | 觸發條件 |
---|---|
onclick | 鼠標點擊左鍵觸發 |
onmouseover | 鼠標經過觸發 |
onmouseout | 鼠標離開觸發 |
onmousemove | 鼠標移動觸發 |
onmouseenter | 鼠標經過觸發 |
onmouseleave | 鼠標離開觸發 |
onfocus | 獲得鼠標焦點觸發 |
onblur | 失去鼠標焦點觸發 |
onmouseup | 鼠標彈起觸發 |
onmousedown | 鼠標按下觸發 |
<body>
無法複製的文字
<script>
// 1. contextmenu 我們可以禁用右鍵菜單
document.addEventListener('contextmenu', function(e) {
alert('請尊重勞動成果');
e.preventDefault();
})
// 2. 禁止選中文字 selectstart
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
</script>
</body>
7.2 鼠標事件對象
event 對象代表事件的狀態,跟事件相關的一系列信息的集合,現階段主要是事件對象
MouseEvent 和鍵盤事件 KeyboardEvent。
鼠標事件對象 | 說明 |
---|---|
e.clientX | 返回鼠標相對於瀏覽器窗口可視區域的 X 座標 |
e.clientY | 返回鼠標相對於瀏覽器窗口可視區域的 Y 座標 |
e.pageX | 返回鼠標相對於文檔頁面的 X 座標 IE9+ 支持 |
e.pageY | 返回鼠標相對於文檔頁面的 Y 座標 IE9+ 支持 |
e.screenX | 返回鼠標相對於電腦屏幕的 X 座標 |
e.screenY | 返回鼠標相對於電腦屏幕的 Y 座標 |
<body>
無法複製的文字
<script>
// 鼠標事件對象 MouseEvent
document.addEventListener('click', function() {
// 1. client 鼠標在可視區域的 x 和 y 的座標
console.log(e.clientX);
console.log(e.clientY);
console.log("------------------------");
// 2. page 鼠標在頁面文檔中的 x 和 y 座標
console.log(e.pageX);
console.log(e.pageY);
console.log("------------------------");
// 3. screen 鼠標在電腦屏幕的 x 和 y 座標
console.log(e.screenX);
console.log(e.screenY);
})
</script>
</body>
案例:
8. 常用的鍵盤事件
8.1 事件除了使用鼠標觸發,還可以使用鍵盤觸發
鍵盤事件 | 觸發條件 |
---|---|
onkeyup | 某個鍵盤按鍵被鬆開時觸發 |
onkeydown | 某個鍵盤按鍵被按下時觸發 (先執行這個) |
onkeypress | 某個鍵盤按鍵被按下時觸發 但是不識別功能鍵 比如 ctrl shift 箭頭等 |
注意:
- 如果使用addEventListener 不需要加 on
- onkeypress 和前面兩個的區別是,他不識別功能鍵,比如左箭頭,shift 等
- 三個事件的執行順序是:keydown --> keypress --> keyup
<body>
<script>
// 1. 鍵盤按下時觸發
document.addEventListener('keyup', function() {
console.log('我彈起了');
})
// 2. 鍵盤彈起時觸發
document.addEventListener('keydown', function() {
console.log('我按下了');
})
// 3. keypress 按鍵按下時觸發
document.addEventListener('keypress', function() {
console.log('我按下了keypress');
})
</script>
</body>
8.2 鍵盤事件對象
鍵盤事件對象 屬性 | 說明 |
---|---|
keyCode | 返回該鍵的 ASCLL 值 |
注意:
- onkeydown 和 onkeyup 不區分大小寫,onkeypress 區分字母大小寫。
- 在實際開發中,我們更多的使用 keydown 和 keyup,它能識別所有的鍵(包括功能鍵)
- Keypress 不識別功能鍵,但是keyCode區分大小寫,返回不同的ASCLL碼值