Dom事件模型

Dom Leval0

例子html

若是想要用戶點擊按鈕就能打印「hello world」,html中的格式該如何寫?在A、B、C之間不定項選擇 若是想要用戶點擊按鈕就能打印「hello world」,js中的格式應該如何寫?在X、Y、Z之間不定項選擇程序員

答案: B、C 和 X編程

注意數組

  • 不能覺得html中怎麼寫js中就應該怎樣寫,它們是2種不一樣的語言瀏覽器

  • 在html中onclick到底再作什麼? ---> onclick = "要執行的代碼",一旦用戶點擊,瀏覽器就eval("要執行的代碼"),若是再控制檯eval('print')和直接在控制檯中寫print沒有任何的區別,若是要執行print還須要在後面加括號print()或者print.call()數據結構

  • 在js中一旦用戶點擊,那麼瀏覽器就幫咱們執行(以X爲例子)調用函數 X.onclick.call(函數裏面的this,函數的arguments[0]),因此X.onclick的返回類型必定爲函數,那麼X.onclick = print中的print的類型爲函數對象就能對上了,然而Y.onclick = print()中的print()它的返回類型是undefined,因此選擇Y是錯的。一樣的Z.onclick = print.call()中的print.call()它的返回類型也爲undefined,因此Z也是錯的。即在html中是須要加()的由於須要的是要執行代碼,在js中是不要加()的由於須要的是函數,不須要調用它,須要等瀏覽器去調用它函數

  • 做爲程序員必定要關注返回的數據類型而不是用眼睛去編程this

Dom Leval2

Dom Leveal2中的寫法:code

實例cdn

xxx.addEventListener()xxx.onclick = function(){}這種形式的區別是什麼?

注意

  • 後者只是元素的一個屬性而已,一個元素只有一個onclick屬性。一旦給這個元素綁定2個onclick屬性那就完了,最後寫的會覆蓋以前寫的,若是是多人合做的項目,別人也用onclick監聽了該元素,那麼就不敢輕易的給元素加onclick屬性,萬一不當心覆蓋了別人的代碼,這樣就很不友好了!

  • 前者就不會出現這種問題了,它屬於數據結構中的隊列,先進先出,叫事件監聽隊列

實例

運行結果爲打印2,事件監聽隊列,就是數據結構中的隊列,先進先出,回顧一下整個過程:

首先是f1進入隊列,而後是f2進入隊列,而後f1又離開了隊列,而後f3又進入隊列,而後f3又離開了隊列,最後只剩下f2在隊列中了

實例

以上就是.one()內部實現的原理,進入隊列一次,執行完代碼後又當即移出事件監聽隊列,因此使用.one()進行一次事件監聽後第二次再怎麼點都沒反應了,由於它已經不在事件監聽隊列中了,一旦沒有btn.removeEventListener('click',f1)這句話,持續的點擊按鈕會一直的輸出打印1

總結:

事件隊列模型:

不一樣的事件有不一樣的事件隊列,click有click本身的隊列,mouseenter有它本身的隊列,它們站本身的隊 ,先進的先出,隊列能夠理解我數組,每次add就向這個數組容器裏添加一個函數,每次remove就向這個 數組刪除一個數,當用戶觸發事件的時候就會依次的按照進入數組(隊列)的順序調用一遍,remove就是不 想處理這個事件,就從事件隊列(數組)中離開

容器裏添加一個函數

事件模型

實例

Q1:當點擊兒子的時候是否點擊了爸爸和爺爺

答案是yes

Q2:當點擊兒子的時候,3個函數是否調用

答案是yes

Q3:請問f1,f2,f3的執行順序

w3c:均可以

Q4:不傳第三個參數或者傳false

執行順序:兒子--->爸爸--->爺爺

幾個falsy值: 0 NaN '' null undefined false

Q5: 傳第三個參數爲true

執行順序: 爺爺 ---> 爸爸 ---> 兒子

事件模型

先捕獲再冒泡

若是捕獲階段有插入函數就調用函數,若是沒有插入函數就不調用函數;

冒泡階段也是同樣,若是有插入函數就調用函數,若是沒有插入函數就不調用函數;

那麼如何知道插入的是捕獲階段仍是冒泡階段呢?

就是經過第三個參數true或false來選擇,若是傳的是false,就跑到右邊的冒泡階段,若是傳的是true就

跑到左邊的捕獲階段

一個特殊狀況要單獨記:

若是被點擊的元素既有捕獲階段又有冒泡階段,那麼最終的執行順序是書寫的順序去執行

相關文章
相關標籤/搜索