1.何謂事件
用戶和網(wǎng)頁交互時(shí)的行為,動(dòng)作,稱之為事件;
2.監(jiān)視事件
現(xiàn)實(shí)生活中焦读,為了監(jiān)視車輛是否違章表鳍,通過在紅綠燈安裝攝像頭監(jiān)視車輛骇窍,我們?cè)诰W(wǎng)頁中要想知道用戶是否某個(gè)行為是否發(fā)生了,也需要安裝監(jiān)聽器進(jìn)行監(jiān)視,這樣當(dāng)用戶的行為發(fā)生時(shí)饼煞,我們要做相應(yīng)的處理源葫,從而提升用戶體驗(yàn).
我們監(jiān)視用戶的行為(事件)是否發(fā)生了,有3種方式:
(1)將事件監(jiān)聽器綁定在html標(biāo)簽上,作為標(biāo)簽屬性存在
例如我們監(jiān)聽用戶點(diǎn)擊的行為,可采取這種寫法<a href="onclick">
,通過on關(guān)鍵字加監(jiān)視的行為(事件),這種方式由于html標(biāo)簽和javascript代碼緊密耦合在一塊,這樣不是非常的靈活;
(2)DOM0級(jí)事件監(jiān)聽
將事件監(jiān)聽器綁定在DOM節(jié)點(diǎn)對(duì)象上
(3)DOM2級(jí)事件監(jiān)聽
DOM2級(jí)事件定義了兩個(gè)方法用于處理指定和刪除事件處理程序的操作:
- addEventListener
- removeEventListener
所有的DOM節(jié)點(diǎn)都包含這兩個(gè)方法,并且它們都接受三個(gè)參數(shù): - 事件類型
- 事件處理方法
- 布爾參數(shù)砖瞧,如果是true表示在捕獲階段調(diào)用事件處理程序息堂,如果是false,則是在事件冒泡階段處理
//參數(shù)1:事件類型 click块促,沒有on
//參數(shù)2:事件發(fā)生時(shí)執(zhí)行的函數(shù)
//參數(shù)3:是否捕獲荣堰,true捕獲、false非捕獲-事件冒泡(100%----false)
- IE(6-7-8)等瀏覽器通過attachEvent方法進(jìn)行監(jiān)聽,通過detachEvent來移除監(jiān)聽程序
在這里需要特別注意的是IE瀏覽器只支持事件冒泡的事件流,添加的事件處理程序發(fā)生在事件冒泡階段;
參數(shù)1:事件類型:加上on關(guān)鍵字
參數(shù)2:事件發(fā)生時(shí)執(zhí)行的函數(shù)
將上述代碼進(jìn)行簡單的封裝,保存到common.js文件中,之后導(dǎo)入主文件中進(jìn)行調(diào)用
封裝如下:
3.事件流
事件流描述的是從頁面中接收事件的順序竭翠,比如有兩個(gè)嵌套的div振坚,點(diǎn)擊了內(nèi)層的div,這時(shí)候是內(nèi)層的div先觸發(fā)click事件還是外層先觸發(fā)斋扰?目前主要有三種模型:
(1) IE的事件冒泡:事件開始時(shí)由最具體的元素接收渡八,然后逐級(jí)向上傳播到較為不具體的元素
(2) Netscape的事件捕獲:不太具體的節(jié)點(diǎn)更早接收事件,而最具體的元素最后接收事件传货,和事件冒泡相反
(3) DOM事件流:DOM2級(jí)事件規(guī)定事件流包括三個(gè)階段呀狼,事件捕獲階段,處于目標(biāo)階段损离,事件冒泡階段,首先發(fā)生的是事件捕獲绝编,為截取事件提供機(jī)會(huì)僻澎,然后是實(shí)際目標(biāo)接收事件,最后是冒泡階段
采用以下實(shí)例來說明這種事件關(guān)系:
4.事件捕獲和事件冒泡
事件捕獲:先執(zhí)行父元素身上的事件,再執(zhí)行自身.設(shè)置為true;
事件冒泡:先執(zhí)行自己身上的事件,再執(zhí)行父元素身上的.設(shè)置false;
阻止事件冒泡:
通過事件對(duì)象阻止十饥,事件對(duì)象是當(dāng)事件(用戶行為)發(fā)生的時(shí)候窟勃,會(huì)自動(dòng)產(chǎn)生的一個(gè)對(duì)象,而且這個(gè)對(duì)象會(huì)自動(dòng)傳遞到函數(shù)里面逗堵,通常我們會(huì)通過事件對(duì)象來獲得當(dāng)行為發(fā)生時(shí)秉氧,事件主題的信息(坐標(biāo)、左擊蜒秤、右擊等)
分別將執(zhí)行事件的stopPropogation方法和將cancleBubble屬性設(shè)置為true,可以阻止主流瀏覽器和IE瀏覽器的事件冒泡現(xiàn)象;
- event.stopPropogation()
- event.cancleBubble = true
5.事件對(duì)象
DOM中的事件對(duì)象
在觸發(fā)DOM上的某個(gè)事件的時(shí)候會(huì)產(chǎn)生一個(gè)事件對(duì)象event汁咏,這個(gè)對(duì)象包含著所有與事件有關(guān)的信息,包括產(chǎn)生事件的元素作媚、事件類型等相關(guān)信息攘滩。所有瀏覽器都支持event對(duì)象,但支持方式不同纸泡。
event對(duì)象包含與創(chuàng)建它的特定事件有關(guān)的屬性和方法漂问,觸發(fā)事件的類型不同,可用的屬性和方法也不同,但是所有事件都會(huì)包含
6.事件分類
(1)鼠標(biāo)事件:用戶鼠標(biāo)的行為
- click :鼠標(biāo)單擊事件
- dbclick:鼠標(biāo)雙擊行為(連續(xù)點(diǎn)擊)
- mousedown:鼠標(biāo)按下行為
- mouseup:鼠標(biāo)抬起行為
通常應(yīng)用場(chǎng)景:鼠標(biāo)按下的時(shí)候,獲得是左擊還是右擊?通過事件對(duì)象的button屬性來獲得:- button屬性為:0表示鼠標(biāo)左擊
- button屬性為:1表示滑輪按下
- button屬性為:2表示鼠標(biāo)右擊
- mouseover:鼠標(biāo)移入(會(huì)出現(xiàn)事件冒泡,不僅執(zhí)行子元素上的事件,而且還會(huì)執(zhí)行父元素上的事件)
- mouseout:鼠標(biāo)移除(會(huì)出現(xiàn)事件冒泡,不僅執(zhí)行子元素上的事件,而且還會(huì)執(zhí)行父元素上的事件)
- mouseenter,mouseleave:鼠標(biāo)移入,移出的行為(阻止事件冒泡)
要注意這兩個(gè)鼠標(biāo)移入移出事件與mouseover以及mouseout事件的區(qū)別在于是否阻止了事件冒泡機(jī)制;
如上圖,可見當(dāng)鼠標(biāo)移入子元素的時(shí)候,發(fā)生了事件冒泡現(xiàn)象,父元素的事件監(jiān)聽也執(zhí)行了;
如上圖,可見當(dāng)鼠標(biāo)移入子元素的時(shí)候,只會(huì)執(zhí)行子元素上的事件監(jiān)聽程序,而不會(huì)發(fā)生事件冒泡現(xiàn)象
- mousemove:鼠標(biāo)移動(dòng)(放大鏡)
通常通過鼠標(biāo)移動(dòng)的時(shí)候,獲得事件發(fā)生時(shí)鼠標(biāo)所在的位置
通過事件對(duì)象的
clientX蚤假、clientY:獲得距離客戶端(瀏覽器)的距離(不包含滾動(dòng)條卷去的高度)
pageX栏饮、pageY:獲得距離頁面的距離(包含滾動(dòng)條卷去的高度)
- scroll:鼠標(biāo)滑輪滾動(dòng)行為
說明:由于scroll監(jiān)視的是body整體在滑動(dòng),所以事件應(yīng)該監(jiān)視在body身上去
獲得每次滑輪滾動(dòng)時(shí)磷仰,滾動(dòng)的距離袍嬉,通過scrollTop獲得滾動(dòng)距離,而scrollHeight獲得滾動(dòng)條總的高度;- scrollTop:獲得滾動(dòng)條每次滾動(dòng)的距離(距離頂部的距離)
- scrollLeft:獲得滾動(dòng)條每次滾動(dòng)的距離(距離左邊的距離)
- scrollHeight:獲得滾動(dòng)條總的高度
(2)鍵盤事件:用戶鍵盤行為
說明:監(jiān)視用戶的鍵盤的行為芒划,用戶可以通過鍵盤和網(wǎng)頁進(jìn)行交互
javascript設(shè)計(jì)者給每一個(gè)按鍵分配了一個(gè)ASCII碼冬竟,通過事件對(duì)象的keyCode屬性獲得這個(gè)ASCII碼:
比如當(dāng)我們按下w鍵時(shí),對(duì)應(yīng)的ASCLL碼值為87,同理s鍵對(duì)應(yīng)的是83.a鍵對(duì)應(yīng)的是65,d鍵對(duì)應(yīng)的是68;
有3個(gè)按鍵是特殊:
ctrl鍵 ----------- event.ctrlKey屬性
shift鍵---------- event.shiftKey屬性
alt鍵----------- event.altKey屬性
這三個(gè)按鍵只有當(dāng)我們按下的時(shí)候,對(duì)應(yīng)的這3個(gè)屬性才為true
將來我們只需要判斷只要ctrlKey屬性為true民逼,說明ctrl鍵被按下了泵殴,只要altKey屬性為true,說明altKey屬性被按下了
- keydown:鍵盤按鍵按下
- keyup:鍵盤按鍵抬起
(3)表單事件
submit:表單提交事件(表單提交行為)
通常監(jiān)視這個(gè)提交的行為拼苍,一旦提交行為發(fā)生了笑诅,我們要去驗(yàn)證輸入框的內(nèi)容是否合法,如果不符合規(guī)則疮鲫,則阻止表單提交到服務(wù)器;select:輸入框內(nèi)容被選中行為
focus:輸入框獲得光標(biāo),獲得焦點(diǎn)行為
blur:輸入框失去光標(biāo),失去焦點(diǎn)行為
change:監(jiān)視下拉列表內(nèi)容發(fā)生變化行為
reset:重置按鈕被點(diǎn)擊的行為
(4)頁面加載完畢事件
load:某個(gè)網(wǎng)頁以及圖像被完整加載
復(fù)習(xí)部分
題目1: DOM0 事件和DOM2級(jí)在事件監(jiān)聽使用方式上有什么區(qū)別吆你?
DOM0級(jí)事件和DOM2級(jí)在時(shí)間監(jiān)聽使用方式的區(qū)別在于:
DOM0級(jí)事件
是將事件監(jiān)聽器綁定在DOM節(jié)點(diǎn)上,事件處理程序是被認(rèn)為是當(dāng)前綁定節(jié)點(diǎn)元素的事件處理屬性的值,事件處理程序是在元素的作用域下運(yùn)行,this指的是當(dāng)前的元素;要注意的是一個(gè)事件只能綁定一次,如果綁定了新方法,則新方法會(huì)覆蓋舊方法;DOM2級(jí)事件 定義了addEventListener,removeEventLIstener兩種方法用于處理指定和刪除事件處理程序的操作;所有的DOM節(jié)點(diǎn)都包含這兩個(gè)方法,并且它們都接受三個(gè)參數(shù):事件類型俊犯、事件處理方法妇多、布爾參數(shù)。本質(zhì)是通過DOM節(jié)點(diǎn)特定的綁定事件監(jiān)聽程序來進(jìn)行事件處理;
題目2: attachEvent與addEventListener的區(qū)別燕侠?
attachEvent與addEventListener的區(qū)別在于:
兼容性上的區(qū)別,attachEvent是老版本IE上綁定事件處理程序的方法,而addEventListener是主流瀏覽器上的綁定事件處理程序的方法;
參數(shù)個(gè)數(shù)不相同者祖,addEventListener有三個(gè)參數(shù),attachEvent只有兩個(gè)绢彤,attachEvent添加的事件處理程序只能發(fā)生在冒泡階段七问,addEventListener第三個(gè)參數(shù)可以決定添加的事件處理程序是在捕獲階段還是冒泡階段處理(我們一般為了瀏覽器兼容性都設(shè)置為冒泡階段)
第一個(gè)參數(shù)意義不同,addEventListener第一個(gè)參數(shù)是事件類型(比如click茫舶,load)械巡,而attachEvent第一個(gè)參數(shù)指明的是事件處理函數(shù)名稱(onclick,onload)
事件處理程序的作用域不相同饶氏,addEventListener的作用域是元素本身讥耗,this是指的觸發(fā)元素,而attachEvent事件處理程序會(huì)在全局變量內(nèi)運(yùn)行嚷往,this是window葛账,所以會(huì)返回undefined,而不是元素id皮仁。
為一個(gè)事件添加多個(gè)事件處理程序時(shí)籍琳,執(zhí)行的順序不同菲宴。 addEventListener 會(huì)按照添加的順序執(zhí)行。 attachEvent 添加多個(gè)事件處理程序時(shí)趋急,順序是無規(guī)律的喝峦。
題目3: 解釋IE事件冒泡和DOM2事件傳播機(jī)制?
事件開始時(shí)由最具體的元素接收呜达,然后逐級(jí)向上傳播到較為不具體的元素;
假如將DOM節(jié)點(diǎn)各級(jí)都綁定了事件監(jiān)聽器,那么當(dāng)發(fā)生IE事件冒泡時(shí),會(huì)從子類元素的事件處理程序開始執(zhí)行,一級(jí)一級(jí)向上執(zhí)行各級(jí)的事件冒泡程序;DOM2級(jí)事件規(guī)定事件流包括三個(gè)階段谣蠢,事件捕獲階段,處于目標(biāo)階段查近,事件冒泡階段眉踱,首先發(fā)生的是事件捕獲,為截取事件提供機(jī)會(huì)霜威,然后是實(shí)際目標(biāo)接收事件谈喳,最后是冒泡階段;
題目4:如何阻止事件冒泡? 如何阻止默認(rèn)事件戈泼?
要阻止事件的默認(rèn)行為婿禽,可以使用preventDefault()方法,前提是cancelable值為true
stopPropagation()方法可以停止事件在DOM層次的傳播大猛,即取消進(jìn)一步的事件捕獲或冒泡
而要阻止在IE上的事件冒泡發(fā)生,則可將事件對(duì)象的cancleBubble 屬性設(shè)置為true;
題目5:有如下代碼扭倾,要求當(dāng)點(diǎn)擊每一個(gè)元素li時(shí)控制臺(tái)展示該元素的文本內(nèi)容。不考慮兼容
<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: 補(bǔ)全代碼挽绩,要求:
- 當(dāng)點(diǎn)擊按鈕開頭添加時(shí)在<li>這里是</li>元素前添加一個(gè)新元素膛壹,內(nèi)容為用戶輸入的非空字符串;當(dāng)點(diǎn)擊結(jié)尾添加時(shí)在最后一個(gè) li 元素后添加用戶輸入的非空字符串.
- 當(dāng)點(diǎn)擊每一個(gè)元素li時(shí)控制臺(tái)展示該元素的文本內(nèi)容唉堪。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul class="ct">
<li>測(cè)試數(shù)據(jù)1</li>
<li>測(cè)試數(shù)據(jù)2</li>
<li>測(cè)試數(shù)據(jù)3</li>
</ul>
<input type="text" class="ipt-add-content" placeholder="添加內(nèi)容"/>
<button id="btn-add-start">開頭添加</button>
<button id="btn-add-end">結(jié)尾添加</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('文本輸入框必須輸入內(nèi)容');
return;
}else{
let newLi=document.createElement('li');
newLi.innerText=ipt.value;
ct.appendChild(newLi);
ipt.value='';
}
});
addStartBtn.addEventListener('click', function(){
if(!ipt.value){
alert('文本輸入框必須輸入內(nèi)容');
return;
}else{
let newLi=document.createElement('li');
newLi.innerText=ipt.value;
ct.insertBefore(newLi, ct.firstChild);
ipt.value='';
}
});
</script>
</body>
</html>
題目7: 補(bǔ)全代碼恢筝,要求:當(dāng)鼠標(biāo)放置在li元素上,會(huì)在img-preview里展示當(dāng)前l(fā)i元素的data-img對(duì)應(yīng)的圖片巨坊。
<!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">鼠標(biāo)放置查看圖片</li>
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg">鼠標(biāo)放置查看圖片</li>
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg">鼠標(biāo)放置查看圖片</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")
//利用循環(huán)來綁定事件
/*for(var i=0;i<list.length;i++){
list[i].addEventListener('click', function(){
//設(shè)置data-img變量來存儲(chǔ)圖片的網(wǎng)絡(luò)地址
var data_img = this.getAttribute("data-img");
preview.innerHTML = "![]("+data_img+")";
}, false)
}
*/
//利用事件代理來實(shí)現(xiàn)事件綁定
ct.addEventListener('click', function(e){
var data_img = e.target.getAttribute('data-img');
preview.innerHTML = "![]("+data_img+")";
}, false)
</script>
</body>
</html>