1.何謂事件
用戶和網頁交互時的行為,動作,稱之為事件;
2.監視事件
現實生活中,為了監視車輛是否違章,通過在紅綠燈安裝攝像頭監視車輛,我們在網頁中要想知道用戶是否某個行為是否發生了,也需要安裝監聽器進行監視,這樣當用戶的行為發生時,我們要做相應的處理,從而提升用戶體驗.
我們監視用戶的行為(事件)是否發生了,有3種方式:
(1)將事件監聽器綁定在html標簽上,作為標簽屬性存在
例如我們監聽用戶點擊的行為,可采取這種寫法<a href="onclick">
,通過on關鍵字加監視的行為(事件),這種方式由于html標簽和javascript代碼緊密耦合在一塊,這樣不是非常的靈活;
(2)DOM0級事件監聽
將事件監聽器綁定在DOM節點對象上
(3)DOM2級事件監聽
DOM2級事件定義了兩個方法用于處理指定和刪除事件處理程序的操作:
- addEventListener
- removeEventListener
所有的DOM節點都包含這兩個方法,并且它們都接受三個參數: - 事件類型
- 事件處理方法
- 布爾參數,如果是true表示在捕獲階段調用事件處理程序,如果是false,則是在事件冒泡階段處理
//參數1:事件類型 click,沒有on
//參數2:事件發生時執行的函數
//參數3:是否捕獲,true捕獲、false非捕獲-事件冒泡(100%----false)
- IE(6-7-8)等瀏覽器通過attachEvent方法進行監聽,通過detachEvent來移除監聽程序
在這里需要特別注意的是IE瀏覽器只支持事件冒泡的事件流,添加的事件處理程序發生在事件冒泡階段;
參數1:事件類型:加上on關鍵字
參數2:事件發生時執行的函數
將上述代碼進行簡單的封裝,保存到common.js文件中,之后導入主文件中進行調用
封裝如下:
3.事件流
事件流描述的是從頁面中接收事件的順序,比如有兩個嵌套的div,點擊了內層的div,這時候是內層的div先觸發click事件還是外層先觸發?目前主要有三種模型:
(1) IE的事件冒泡:事件開始時由最具體的元素接收,然后逐級向上傳播到較為不具體的元素
(2) Netscape的事件捕獲:不太具體的節點更早接收事件,而最具體的元素最后接收事件,和事件冒泡相反
(3) DOM事件流:DOM2級事件規定事件流包括三個階段,事件捕獲階段,處于目標階段,事件冒泡階段,首先發生的是事件捕獲,為截取事件提供機會,然后是實際目標接收事件,最后是冒泡階段
采用以下實例來說明這種事件關系:
4.事件捕獲和事件冒泡
事件捕獲:先執行父元素身上的事件,再執行自身.設置為true;
事件冒泡:先執行自己身上的事件,再執行父元素身上的.設置false;
阻止事件冒泡:
通過事件對象阻止,事件對象是當事件(用戶行為)發生的時候,會自動產生的一個對象,而且這個對象會自動傳遞到函數里面,通常我們會通過事件對象來獲得當行為發生時,事件主題的信息(坐標、左擊、右擊等)
分別將執行事件的stopPropogation方法和將cancleBubble屬性設置為true,可以阻止主流瀏覽器和IE瀏覽器的事件冒泡現象;
- event.stopPropogation()
- event.cancleBubble = true
5.事件對象
DOM中的事件對象
在觸發DOM上的某個事件的時候會產生一個事件對象event,這個對象包含著所有與事件有關的信息,包括產生事件的元素、事件類型等相關信息。所有瀏覽器都支持event對象,但支持方式不同。
event對象包含與創建它的特定事件有關的屬性和方法,觸發事件的類型不同,可用的屬性和方法也不同,但是所有事件都會包含
6.事件分類
(1)鼠標事件:用戶鼠標的行為
- click :鼠標單擊事件
- dbclick:鼠標雙擊行為(連續點擊)
- mousedown:鼠標按下行為
- mouseup:鼠標抬起行為
通常應用場景:鼠標按下的時候,獲得是左擊還是右擊?通過事件對象的button屬性來獲得:- button屬性為:0表示鼠標左擊
- button屬性為:1表示滑輪按下
- button屬性為:2表示鼠標右擊
- mouseover:鼠標移入(會出現事件冒泡,不僅執行子元素上的事件,而且還會執行父元素上的事件)
- mouseout:鼠標移除(會出現事件冒泡,不僅執行子元素上的事件,而且還會執行父元素上的事件)
- mouseenter,mouseleave:鼠標移入,移出的行為(阻止事件冒泡)
要注意這兩個鼠標移入移出事件與mouseover以及mouseout事件的區別在于是否阻止了事件冒泡機制;
如上圖,可見當鼠標移入子元素的時候,發生了事件冒泡現象,父元素的事件監聽也執行了;
如上圖,可見當鼠標移入子元素的時候,只會執行子元素上的事件監聽程序,而不會發生事件冒泡現象
- mousemove:鼠標移動(放大鏡)
通常通過鼠標移動的時候,獲得事件發生時鼠標所在的位置
通過事件對象的
clientX、clientY:獲得距離客戶端(瀏覽器)的距離(不包含滾動條卷去的高度)
pageX、pageY:獲得距離頁面的距離(包含滾動條卷去的高度)
- scroll:鼠標滑輪滾動行為
說明:由于scroll監視的是body整體在滑動,所以事件應該監視在body身上去
獲得每次滑輪滾動時,滾動的距離,通過scrollTop獲得滾動距離,而scrollHeight獲得滾動條總的高度;- scrollTop:獲得滾動條每次滾動的距離(距離頂部的距離)
- scrollLeft:獲得滾動條每次滾動的距離(距離左邊的距離)
- scrollHeight:獲得滾動條總的高度
(2)鍵盤事件:用戶鍵盤行為
說明:監視用戶的鍵盤的行為,用戶可以通過鍵盤和網頁進行交互
javascript設計者給每一個按鍵分配了一個ASCII碼,通過事件對象的keyCode屬性獲得這個ASCII碼:
比如當我們按下w鍵時,對應的ASCLL碼值為87,同理s鍵對應的是83.a鍵對應的是65,d鍵對應的是68;
有3個按鍵是特殊:
ctrl鍵 ----------- event.ctrlKey屬性
shift鍵---------- event.shiftKey屬性
alt鍵----------- event.altKey屬性
這三個按鍵只有當我們按下的時候,對應的這3個屬性才為true
將來我們只需要判斷只要ctrlKey屬性為true,說明ctrl鍵被按下了,只要altKey屬性為true,說明altKey屬性被按下了
- keydown:鍵盤按鍵按下
- keyup:鍵盤按鍵抬起
(3)表單事件
submit:表單提交事件(表單提交行為)
通常監視這個提交的行為,一旦提交行為發生了,我們要去驗證輸入框的內容是否合法,如果不符合規則,則阻止表單提交到服務器;select:輸入框內容被選中行為
focus:輸入框獲得光標,獲得焦點行為
blur:輸入框失去光標,失去焦點行為
change:監視下拉列表內容發生變化行為
reset:重置按鈕被點擊的行為
(4)頁面加載完畢事件
load:某個網頁以及圖像被完整加載
復習部分
題目1: DOM0 事件和DOM2級在事件監聽使用方式上有什么區別?
DOM0級事件和DOM2級在時間監聽使用方式的區別在于:
DOM0級事件
是將事件監聽器綁定在DOM節點上,事件處理程序是被認為是當前綁定節點元素的事件處理屬性的值,事件處理程序是在元素的作用域下運行,this指的是當前的元素;要注意的是一個事件只能綁定一次,如果綁定了新方法,則新方法會覆蓋舊方法;DOM2級事件 定義了addEventListener,removeEventLIstener兩種方法用于處理指定和刪除事件處理程序的操作;所有的DOM節點都包含這兩個方法,并且它們都接受三個參數:事件類型、事件處理方法、布爾參數。本質是通過DOM節點特定的綁定事件監聽程序來進行事件處理;
題目2: attachEvent與addEventListener的區別?
attachEvent與addEventListener的區別在于:
兼容性上的區別,attachEvent是老版本IE上綁定事件處理程序的方法,而addEventListener是主流瀏覽器上的綁定事件處理程序的方法;
參數個數不相同,addEventListener有三個參數,attachEvent只有兩個,attachEvent添加的事件處理程序只能發生在冒泡階段,addEventListener第三個參數可以決定添加的事件處理程序是在捕獲階段還是冒泡階段處理(我們一般為了瀏覽器兼容性都設置為冒泡階段)
第一個參數意義不同,addEventListener第一個參數是事件類型(比如click,load),而attachEvent第一個參數指明的是事件處理函數名稱(onclick,onload)
事件處理程序的作用域不相同,addEventListener的作用域是元素本身,this是指的觸發元素,而attachEvent事件處理程序會在全局變量內運行,this是window,所以會返回undefined,而不是元素id。
為一個事件添加多個事件處理程序時,執行的順序不同。 addEventListener 會按照添加的順序執行。 attachEvent 添加多個事件處理程序時,順序是無規律的。
題目3: 解釋IE事件冒泡和DOM2事件傳播機制?
事件開始時由最具體的元素接收,然后逐級向上傳播到較為不具體的元素;
假如將DOM節點各級都綁定了事件監聽器,那么當發生IE事件冒泡時,會從子類元素的事件處理程序開始執行,一級一級向上執行各級的事件冒泡程序;DOM2級事件規定事件流包括三個階段,事件捕獲階段,處于目標階段,事件冒泡階段,首先發生的是事件捕獲,為截取事件提供機會,然后是實際目標接收事件,最后是冒泡階段;
題目4:如何阻止事件冒泡? 如何阻止默認事件?
要阻止事件的默認行為,可以使用preventDefault()方法,前提是cancelable值為true
stopPropagation()方法可以停止事件在DOM層次的傳播,即取消進一步的事件捕獲或冒泡
而要阻止在IE上的事件冒泡發生,則可將事件對象的cancleBubble 屬性設置為true;
題目5:有如下代碼,要求當點擊每一個元素li時控制臺展示該元素的文本內容。不考慮兼容
<script>
var liArr = document.getElementsByClassName('ct')[0].getElementsByTagName('li')
for(var i=0;i<liArr.length;i++){
liArr[i].addEventListener('click', function(){
console.log(this.innerText);
}, false)
}
</script>
題目6: 補全代碼,要求:
- 當點擊按鈕開頭添加時在<li>這里是</li>元素前添加一個新元素,內容為用戶輸入的非空字符串;當點擊結尾添加時在最后一個 li 元素后添加用戶輸入的非空字符串.
- 當點擊每一個元素li時控制臺展示該元素的文本內容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul class="ct">
<li>測試數據1</li>
<li>測試數據2</li>
<li>測試數據3</li>
</ul>
<input type="text" class="ipt-add-content" placeholder="添加內容"/>
<button id="btn-add-start">開頭添加</button>
<button id="btn-add-end">結尾添加</button>
<script>
var ct=document.querySelector('.ct'),
addStartBtn=document.querySelector('#btn-add-start'),
addEndBtn=document.querySelector('#btn-add-end'),
ipt=document.querySelector('.ipt-add-content');
ct.addEventListener('click',function(e){
if(e.target.tagName.toLowerCase()==='li'){
console.log(e.target.innerText);
}
});
addEndBtn.addEventListener('click', function(){
if(!ipt.value){
alert('文本輸入框必須輸入內容');
return;
}else{
let newLi=document.createElement('li');
newLi.innerText=ipt.value;
ct.appendChild(newLi);
ipt.value='';
}
});
addStartBtn.addEventListener('click', function(){
if(!ipt.value){
alert('文本輸入框必須輸入內容');
return;
}else{
let newLi=document.createElement('li');
newLi.innerText=ipt.value;
ct.insertBefore(newLi, ct.firstChild);
ipt.value='';
}
});
</script>
</body>
</html>
題目7: 補全代碼,要求:當鼠標放置在li元素上,會在img-preview里展示當前li元素的data-img對應的圖片。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul class="ct">
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg">鼠標放置查看圖片</li>
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg">鼠標放置查看圖片</li>
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg">鼠標放置查看圖片</li>
</ul>
<div class="img-preview"></div>
<script text="text/javascript">
var ct = document.querySelector(".ct");
var list = document.querySelectorAll("li");
var preview = document.querySelector(".img-preview")
//利用循環來綁定事件
/*for(var i=0;i<list.length;i++){
list[i].addEventListener('click', function(){
//設置data-img變量來存儲圖片的網絡地址
var data_img = this.getAttribute("data-img");
preview.innerHTML = "";
}, false)
}
*/
//利用事件代理來實現事件綁定
ct.addEventListener('click', function(e){
var data_img = e.target.getAttribute('data-img');
preview.innerHTML = "";
}, false)
</script>
</body>
</html>