聲明:本欄目所使用的素材都是凱哥學(xué)堂VIP學(xué)員所寫(xiě)誊爹,學(xué)員有權(quán)匿名,對(duì)文章有最終解釋權(quán);凱哥學(xué)堂旨在促進(jìn)VIP學(xué)員互相學(xué)習(xí)的基礎(chǔ)上公開(kāi)筆記彼宠。
在用戶使用鍵盤(pán)、鼠標(biāo)等設(shè)備進(jìn)行操作時(shí)弟塞,實(shí)際上每一次的操作都是在發(fā)起一個(gè)事件凭峡。
當(dāng)我們的鼠標(biāo)點(diǎn)擊到窗口上的按鈕時(shí),并不是鼠標(biāo)的箭頭真正點(diǎn)擊到這個(gè)按鈕了决记,而是鼠標(biāo)發(fā)出了一個(gè)動(dòng)作事件摧冀,然后這個(gè)事件先被傳送到了操作系統(tǒng)的命令處理帶,然后再傳送到負(fù)責(zé)顯示圖形的圖像數(shù)據(jù)層系宫,事件到這里后圖像數(shù)據(jù)層會(huì)先看哪個(gè)程序的窗口在最上面(因?yàn)椴皇窃谧钌厦婢蜎](méi)必要看了)索昂,再根據(jù)鼠標(biāo)提供的X Y坐標(biāo)確認(rèn)點(diǎn)擊的是哪個(gè)窗口上的按鈕,接著再確認(rèn)這個(gè)窗口是哪個(gè)程序扩借。
確認(rèn)完畢后椒惨,圖像數(shù)據(jù)層就會(huì)將這個(gè)動(dòng)作事件提交給相對(duì)應(yīng)的執(zhí)行程序,執(zhí)行程序里的代碼先尋找是哪個(gè)位置的數(shù)據(jù)哪個(gè)對(duì)象提供的潮罪,進(jìn)行一系列的搜索康谆,找到后這個(gè)對(duì)象就會(huì)執(zhí)行相對(duì)應(yīng)的代碼,然后再將執(zhí)行后的顯示傳送到圖像數(shù)據(jù)中心進(jìn)行顯示嫉到。我們就會(huì)看到鼠標(biāo)點(diǎn)擊到了這個(gè)按鈕沃暗。
之所以平時(shí)使用的時(shí)候沒(méi)感覺(jué)出來(lái),是因?yàn)檫@一系列的復(fù)雜的機(jī)制都是在瞬間完成的何恶,只有在電腦卡頓的情況下才能感覺(jué)到點(diǎn)擊后要等一段時(shí)間才會(huì)做出相應(yīng)的響應(yīng)孽锥。
示意圖:
這其中有一個(gè)事件委托的概念,我們需要在代碼中把事件委托也可以說(shuō)是注冊(cè)到按鈕上细层,這時(shí)會(huì)有一個(gè)監(jiān)聽(tīng)器監(jiān)聽(tīng)著這個(gè)按鈕忱叭,當(dāng)用戶點(diǎn)擊按鈕時(shí)就會(huì)去調(diào)用委托事件中的代碼隔崎,這些代碼都寫(xiě)在函數(shù)中。
所以簡(jiǎn)單來(lái)說(shuō)韵丑,就是把一個(gè)寫(xiě)好的函數(shù)通過(guò)事件委托到按鈕上爵卒,當(dāng)用戶點(diǎn)擊按鈕后,就會(huì)調(diào)用那個(gè)函數(shù)撵彻,函數(shù)里的代碼就會(huì)執(zhí)行钓株。
例如:我把一段打印Hello World的函數(shù),通過(guò)事件委托到按鈕上陌僵,當(dāng)我點(diǎn)擊這個(gè)按鈕的時(shí)候就會(huì)調(diào)用這個(gè)函數(shù)轴合,函數(shù)執(zhí)行完之后就會(huì)打印Hello World。
以上提到的事件只是眾多事件類(lèi)型中的一種點(diǎn)擊事件碗短,事件是有很多種類(lèi)型的受葛,例如:鼠標(biāo)的單擊、雙擊偎谁、滾軸总滩,鍵盤(pán)的按鍵彈起、按下巡雨、長(zhǎng)按等等闰渔,反正很多就是了,還有一些是某些元素特有的事件铐望。
在介紹如何委托事件前冈涧,先介紹一下如何控制元素對(duì)象(標(biāo)簽對(duì)象),因?yàn)橛行┪惺录姆绞叫枰カ@得元素對(duì)象來(lái)進(jìn)行事件的委托:
第一種獲得方式是通過(guò)id去獲得正蛙,這種方式需要用document對(duì)象去調(diào)用getElementById函數(shù)并傳遞元素的id值督弓,就可以獲得該id值的元素對(duì)象。
代碼示例:
運(yùn)行結(jié)果:
從審查元素中可以看到id值為test_sbutton的元素中的value值乒验,為我js代碼里設(shè)置的值愚隧。
錯(cuò)誤示例:
因?yàn)榇a是是從上至下解析的,如果你要獲得body里面的元素對(duì)象徊件,卻把script寫(xiě)在了body前面奸攻,所以當(dāng)執(zhí)行js里面獲得元素對(duì)象的代碼時(shí)就會(huì)報(bào)錯(cuò):
代碼示例:
運(yùn)行結(jié)果:
第二種方式是直接使用id值蒜危,可以直接拿id值去定義該元素對(duì)象里面的屬性值:
代碼示例:
運(yùn)行結(jié)果:
以上只是介紹比較常見(jiàn)的兩種獲得元素對(duì)象的方式虱痕,除此之外還有很多種獲得方式,可以參考以下文章:
http://www.jb51.net/article/64874.htm
注意:id值不要設(shè)置重復(fù)的最好保持唯一性辐赞,如果設(shè)置重復(fù)的話部翘,js就不能直接獲得元素對(duì)象,而是會(huì)獲得一個(gè)對(duì)象數(shù)組响委,如果遇到id值重復(fù)的情況下新思,就得遍歷數(shù)組去獲得對(duì)象:
代碼示例:
運(yùn)行結(jié)果:
思維導(dǎo)圖:
接下來(lái)開(kāi)始介紹JavaScript中給元素委托事件的三種常用的方式:
第一種方式窖梁,寫(xiě)好函數(shù)代碼后,通過(guò)元素中的事件屬性進(jìn)行委托夹囚,下面用鼠標(biāo)事件中的mouseout和mouseover事件進(jìn)行演示纵刘,mousseout事件在鼠標(biāo)移動(dòng)出該元素時(shí)會(huì)觸發(fā),mouseover事件在鼠標(biāo)移動(dòng)進(jìn)該元素時(shí)會(huì)觸發(fā)荸哟,屬于焦點(diǎn)類(lèi)的事件:
代碼示例:
運(yùn)行結(jié)果:
當(dāng)鼠標(biāo)的光標(biāo)移動(dòng)進(jìn)按鈕時(shí)會(huì)觸發(fā)mouseover事件假哎,移動(dòng)出按鈕時(shí)會(huì)觸發(fā)mousseout事件,然后就會(huì)調(diào)用委托到事件中的函數(shù)代碼鞍历,函數(shù)被調(diào)用執(zhí)行就會(huì)在控制臺(tái)中輸出這些信息舵抹。
所謂焦點(diǎn)就是鼠標(biāo)的光標(biāo)的位置,例如當(dāng)你在文本框輸入文字時(shí)需要點(diǎn)擊一下文本框才能輸入劣砍,這就是要讓文本框獲得鼠標(biāo)焦點(diǎn)惧蛹。
第二種方式,通過(guò)id獲取元素對(duì)象刑枝,然后通過(guò)該對(duì)象調(diào)用事件屬性香嗓,使用函數(shù)表達(dá)式的方式把函數(shù)委托給事件:
代碼示例:
運(yùn)行結(jié)果:
除了函數(shù)表達(dá)式外也可以使用函數(shù)聲明的方式,把函數(shù)的名稱(chēng)賦值給元素對(duì)象的事件屬性仅讽,注意不能寫(xiě)上():
代碼示例:
運(yùn)行結(jié)果:
第三種方式陶缺,通過(guò)addEventListener函數(shù)添加一個(gè)事件監(jiān)聽(tīng)器,需要傳遞事件的名稱(chēng)洁灵,和函數(shù)對(duì)象饱岸,函數(shù)對(duì)象可以是函數(shù)的名稱(chēng),也可以是直接寫(xiě)一個(gè)函數(shù)上去:
代碼示例:
運(yùn)行結(jié)果:
同一個(gè)元素對(duì)象的同一個(gè)事件徽千,可以添加多個(gè)函數(shù)苫费,這些函數(shù)可以執(zhí)行不同的內(nèi)容,例如我在一個(gè)button元素的mouseover事件中分別添加了三個(gè)函數(shù)双抽,這三個(gè)函數(shù)各自打印了一句話百框,那么當(dāng)我鼠標(biāo)碰到按鈕時(shí),就會(huì)打印出三句話:
代碼示例:
運(yùn)行結(jié)果:
addEventListener函數(shù)還有一個(gè)布爾參數(shù)牍汹,這個(gè)參數(shù)定義著父元素和子元素重疊并且都有委托事件的情況時(shí)铐维,是先觸發(fā)父元素的事件還是先觸發(fā)子元素的事件,參數(shù)值為true是定義先觸發(fā)父元素的事件慎菲,參數(shù)值為false則是定義先觸發(fā)子元素的事件嫁蛇,不定義這個(gè)參數(shù)的話,默認(rèn)情況下是先觸發(fā)子元素的事件露该。
父元素和子元素重疊情況睬棚,不定義addEventListener函數(shù)布爾值的代碼示例:
運(yùn)行結(jié)果:
父元素和子元素重疊情況,定義addEventListener函數(shù)布爾值為true的代碼示例:
運(yùn)行結(jié)果:
還有一種情況就是父元素和子元素不完全重疊,這種情況下不定義addEventListener函數(shù)的布爾值抑党,當(dāng)鼠標(biāo)移動(dòng)到子元素時(shí)先觸發(fā)父元素的事件包警,然后移出子元素時(shí)先觸發(fā)子元素的事件再觸發(fā)父元素的事件,這是因?yàn)槟J(rèn)情況下子元素的事件先執(zhí)行底靠,所以父元素的事件不會(huì)連續(xù)執(zhí)行害晦。
定義addEventListener函數(shù)的布爾值為true的話,當(dāng)鼠標(biāo)移動(dòng)到子元素時(shí)先觸發(fā)父元素的事件暑中,然后移出子元素時(shí)還是觸發(fā)父元素的事件篱瞎,最后才觸發(fā)子元素的事件,這是因?yàn)椴紶栔禐閠rue的情況下父元素的事件先執(zhí)行痒芝,所以父元素的事件會(huì)連續(xù)執(zhí)行俐筋。
父元素和子元素不完全重疊的情況,不定義addEventListener函數(shù)布爾值的代碼示例:
運(yùn)行結(jié)果:
父元素的事件不會(huì)連續(xù)執(zhí)行
父元素和子元素不完全重疊的情況严衬,定義addEventListener函數(shù)布爾值為true的代碼示例:
運(yùn)行結(jié)果: 父元素的事件會(huì)連續(xù)執(zhí)行
事件源 Even: 事件源澄者,就是事件產(chǎn)生時(shí)的信息收集,可以通過(guò)事件源對(duì)象獲得很多相關(guān)數(shù)據(jù)请琳,可以設(shè)置元素的屬性粱挡,以下是常見(jiàn)的事件源對(duì)象屬性:
通過(guò)事件源對(duì)象調(diào)用target屬性設(shè)置元素的背景顏色代碼示例:
運(yùn)行結(jié)果:
以上只使用到了鼠標(biāo)事件中的mouseout和mouseover事件,事件還有很多俄精,以下是常見(jiàn)事件的分類(lèi)思維導(dǎo)圖: