例子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 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就
跑到左邊的捕獲階段
一個特殊狀況要單獨記:
若是被點擊的元素既有捕獲階段又有冒泡階段,那麼最終的執行順序是書寫的順序去執行