DOM事件基礎就要結束了,今天整理一下,發上來。做的小案例和練習,有的我沒有放html和css,一般都是使用ul和li做的,大家可以自行搭建吧,主要是學習JavsScript的,但是也不能忘記前面學習的。
事件的註冊和解綁
兩種註冊綁定事件的方式
<script>
// 給li註冊點擊事件
// 傳統方式
var lis = document.querySelector('ul').querySelectorAll('li');
// for (var i = 0; i < lis.length; i++) {
// lis[i].onclick = function () {
// alert('li被點擊了');
// }
// // lis[i].onclick = function () {
// // alert('傳統方式的唯一性'); // 這個註冊事件把上面一個事件給覆蓋掉了
// // }
// }
// 監聽方法註冊事件
for (var i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', fn);
}
function fn() {
alert('add點擊實現li');
alert('可以註冊多個事件');
}
</script>
兩種解除事件綁定的方式
<script>
// 給li註冊點擊事件
// 傳統方式
var lis = document.querySelector('ul').querySelectorAll('li');
var lilis = document.querySelector('.ul').querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
alert('li被點擊了');
// 解綁事件
// 傳統方式的解綁
this.onclick = null;
}
// lis[i].onclick = function () {
// alert('傳統方式的唯一性'); // 這個註冊事件把上面一個事件給覆蓋掉了
// }
}
// 監聽方法註冊事件
for (var i = 0; i < lilis.length; i++) {
lilis[i].addEventListener('click', fn);
}
for (var i = 0; i < lilis.length; i++) {
lilis[i].removeEventListener('click', fn);
}
function fn() {
alert('add點擊實現li');
alert('可以註冊多個事件');
}
</script>
DOM事件的事件流
代碼中的註釋有詳細解釋
其中包含阻止冒泡階段
利用冒泡可以進行事件委託,就是不給子節點添加監聽方法,給父節點添加監聽方法來影響子節點。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
position: relative;
width: 400px;
height: 400px;
background-color: pink;
margin: 100px auto;
}
ul {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>
<body>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<script>
// 事件流:事件的傳播過程叫做事件流
// addEventListener(type, listener[, useCapture])
var div = document.querySelector('div');
var ul = document.querySelector('ul');
var lis = document.querySelectorAll('li');
// 捕獲階段:doucument-->html-->body-->div-->ul-->li
// 冒泡階段:doucument<--html<--body<--div<--ul<--li
// 給li註冊點擊事件
for (var i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', function (e) {
alert('方法監聽實現li被點擊');
// 阻止事件冒泡 給li使用方法阻止冒泡,div的事件就不會觸發了
e.stopPropagation(); // div的事件就沒有執行了 因爲阻止了li的冒泡階段
})
}
// 給div註冊點擊事件
// 先執行的是li的事件,然後冒泡得到div的事件 因爲方法監聽的第三個參數省略不寫得到的是冒泡階段
// 把第三個參數設爲:true 得到的是捕獲階段:先得到div事件,再得到li的事件
// 爲false或者省略不寫 得到的是冒泡階段 先得到li事件,再得到div的事件
div.addEventListener('click', function () {
alert('div被點擊');
}, false)
</script>
</body>
</html>
事件對象
鼠標事件
實現案例:圖片跟着鼠標移動。
<script>
// 常用事件對象的方法和屬性
// preventDefault()方法 阻止默認事件
// target屬性:返回的是觸發事件的對象元素
// type屬性:返回的是事件類型
// 常用的事件對象 鼠標事件和鍵盤事件
// 鼠標常用事件:contextmenu selectstart
// contextmenu 禁止鼠標右鍵 preventDefault方法 阻止默認行爲
// selectstart 禁止文字被選中
var lis = document.querySelector('ul').querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
// 在li上鼠標是無法右鍵彈出菜單的
lis[i].addEventListener('contextmenu', function (e) {
e.preventDefault();
e.returnValue; //兼容ie678的寫法
})
// li中的文字無法被選中
lis[i].addEventListener('selectstart', function (e) {
e.preventDefault();
})
}
// 鼠標事件對象中常用的屬性 client系列:是鼠標位置距離可視窗口水平和垂直的距離
// page系列:是鼠標位置距離頁面頂部(左上角)水平和垂直距離
document.addEventListener('click', function (e) {
console.log(e.clientX);
console.log(e.clientY);
console.log(e.pageX);
console.log(e.pageY);
})
// 鼠標事件對象的案例:圖片跟隨鼠標移動
var img = document.querySelector('img');
document.addEventListener('mousemove', function (e) {
// 坑:一定要加單位 px
var x = e.clientX;
var y = e.clientY;
img.style.top = y - 50 + 'px';
img.style.left = x - 40 + 'px';
})
</script>
鍵盤事件
案例:判斷用戶輸入的字母是否爲s,是的話表單自動獲得焦點
<script>
// 鍵盤事件
// keyup:鍵盤彈起觸發 文本不會錄入文本框
// keydown:鍵盤按下觸發 不識別字母大小寫 文本會錄入文本框
// keypress:鍵盤下觸發
// keyCode 可以識別 返回的是字符對應的ASCII值
// 實現按下s鍵,搜索框自動獲焦
var search = document.querySelector('input');
document.addEventListener('keyup', function (e) {
if (e.keyCode == 83) {
search.focus();
console.log(e.keyCode);
}
})
</script>
案例:查詢快遞單號
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, .2);
box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="請輸入您的快遞單號" class="jd">
</div>
<script>
// 快遞單號輸入內容時, 上面的大號字體盒子(con)顯示(這裏面的字號更大)
// 表單檢測用戶輸入: 給表單添加鍵盤事件
// 同時把快遞單號裏面的值(value)獲取過來賦值給 con盒子(innerText)做爲內容
// 如果快遞單號裏面內容爲空,則隱藏大號字體盒子(con)盒子
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
jd_input.addEventListener('keyup', function () {
// console.log('輸入內容啦');
if (this.value == '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
})
// 當我們失去焦點,就隱藏這個con盒子
jd_input.addEventListener('blur', function () {
con.style.display = 'none';
})
// 當我們獲得焦點,就顯示這個con盒子
jd_input.addEventListener('focus', function () {
if (this.value !== '') {
con.style.display = 'block';
}
})
</script>
</body>
</html>
效果
最後附上我的學習筆記。
DOM事件學習筆記
###註冊事件的兩種方式
傳統方式:
事件源.事件類型 = 事件處理程序
方法監聽註冊:
1.使用addEventListener()方法 存在兼容性問題:支持ie9以上
事件源.addEventListener('type',listener)
addEventListener()方法有三個參數
type:事件類型
listener:處理函數,也叫監聽器,就是事件處理程序的函數
這裏的處理函數可以寫在外面,添加監聽時直接調用函數名即可
useCapture:判斷是捕獲還是冒泡過程,可選參數
2.使用attachEvent()方法 ie678支持,使用方法與addEventListener()相同兩種方式的區別
1.傳統方式註冊事件,具有唯一性,簡單來說就是同一元素同一個事件只能註冊一次
方法監聽註冊可以同一元素同一事件可以註冊多個監聽器
2.傳統方式的事件類型帶 on,比如 onclick、onmouseover等
方法監聽的事件類型不帶 on,比如 click mouseover等###刪除事件
傳統方式:
事件源.事件類型 = null
方法監聽方式:
事件源.removeEventListener('type',listener)###DOM事件流
概念:事件的傳播過程就是DOM事件流
事件流的三個階段
1.捕獲階段
事件從最頂層節點(document)往裏層找當前目標
2.當前目標階段
監聽事件的元素
3.冒泡階段
事件從當前目標往頂層節點找
方法監聽的第三個參數:
useCapture:
true —— 捕獲階段
false\省略不寫 —— 冒泡階段
事件流注意點
JS代碼只能獲取捕獲階段或者冒泡階段
有些事件是沒有冒泡階段的:onfocus、onblur、onmouseenter、onmouseleave
attachEvent()和onclick只能得到冒泡階段###事件對象 addEventListener('click',function(e){})
常用事件一般包括的是鼠標事件和鍵盤事件
事件對象的解釋
事件對象是事件的一系列相關數據的集合
事件對象只有事件存在,纔會有事件對象
事件的處理函數中的一個參數(形參),就是事件對象event都可以
事件對象是系統自動創建的,不需要我們傳輸參數,直接使用。其中event是程序員可以自定義的evt、e都可以表示事件對象
ie678,通過window.event 獲取事件對象,參數必須是event
常見事件對象的屬性和方法
方法
e.preventDefault() 方法:阻止事件默認行爲 比如說:讓連接不跳轉、按鈕不能提交等
e.returnValue 是屬性 阻止事件默認行爲 爲了兼容ie678
屬性
e.target 返回的是觸發事件的對象(元素) 誰觸發事件,返回誰
與this區別:this是誰綁定事件(註冊事件、添加監聽)返回誰
e.type 返回的是事件類型###阻止事件冒泡
使用事件對象方法
e.stopPropagation() 方法
e.cancelBubble = true###事件委託
原理
不在每個子節點上添加監聽器,而是在子節點的父節點上添加監聽,利用冒泡原理影響設置每個子節點
作用
DOM操作次數減少,提高程序性能###常用的鼠標事件
禁止鼠標右鍵:contextmenu
ele.addEventListener('contextmenu',function(e){
e.preventDefault();
})
禁止選中文字:selectstart
ele.addEventListener('selectstart',function(e){
e.preventDefault();
}
###鼠標事件對象 MouseEvent中常用的屬性
e.clientX 返回的是鼠標距離可視區域頂部的距離 可視區域就是眼睛看到的那一個矩形
e.clientY 返回的是鼠標距離可視區域左邊的距離
e.pageX 返回的是鼠標距離頁面頂部距離
e.pageY 返回的是鼠標距離頁面左側距離
實現一個案例:圖片跟着鼠標移動 鼠標到哪圖片跟着到哪。實質就是獲取鼠標的位置,把位置數據複製給圖片的top和left###常用鍵盤事件
keyup:鍵盤彈起,鬆開時觸發事件
keydown:鍵盤按下,按鍵盤點擊時觸發事件
keypress:鍵盤按下觸發事件
keydown和keypress的區別
keydown 不區別字母大小寫;keypress不識別功能鍵,比如ctrl等
二者均是在按下按鍵觸發事件,在執行時,keydown先於keypress執行
鍵盤事件對象常用的屬性
e.keyCode 返回的是字符的ASCII字符編碼
用此屬性判斷字母大小寫
實例:檢測用戶輸入的字符 s可以使搜索框自動獲焦點 表單的focus()方法——獲焦
keydown和keypress在文本框中的特點:
這兩個事件觸發的時候,文字還沒有落入文本框。因爲在按下的那一瞬間就觸發了事件,文字還沒來得及存入文本框
keyup事件觸發是在鬆開時,這是文字已經落入文本框內