iT邦幫忙

14

[筆記][JavaScript]所謂的「停止事件」到底是怎麼一回事?

HI!大家好,好久沒有記錄JavaScript的筆記了XD,在昨天研究Vue的時後突然看到了沒看過的東西,其實還有很多啦!只是這兩個function就剛好被我遇到,所以去查了一下他們的原理,欸!說了那麼多那到底是什麼?以下文章開始!

首先提一下JavaScript的事件,不管是onclickonchange都會有個事件的物件產生,這個物件稱他為event,他會紀錄著事件觸發的狀態,包括是因為什麼觸發到他是在什麼DOM上觸發的,都會紀錄在event當中,而文章中的就是要說關於event中的兩件事情。

1. event.stopPropagation()

講這個function之前也要先補充一些知識,首先我們看以下圖片:
https://ithelp.ithome.com.tw/upload/images/20180828/20106935TQrsfxRteG.jpg
我在HTML下了兩個div,並在最裡面的div放一個button,以及為他們三個都各設定一個click事件,但是當我點擊button的時候會發現同時觸發了外面兩層div的事件,因為三個DOM很剛好的重疊了,所以點擊後會觸發所有的click事件,這個現象我們稱呼為「事件冒泡」。

有時候我們是不希望「事件冒泡」發生在程式碼中,所以才有了event.stopPropagation()函式!他的作用就是為了阻止事件繼續冒泡,下方將event.stopPropagation()加入程式碼中:
https://ithelp.ithome.com.tw/upload/images/20180829/20106935SEmaP5JSxg.jpg

事件的第一個參數就是上述提到的事件物件event,一般的狀況下都可以這樣去取,另外也可以透過window.event去得到相同的事件物件,可以用嚴格等於去比較他:
https://ithelp.ithome.com.tw/upload/images/20180829/201069356c7lJXaO0i.jpg

所以event.stopPropagation()是指阻止事件冒泡,經過解釋後是不是清楚多了!那緊接著第二個函式。

2. event.preventDefault()

第二個函式比較容易,他的作用是停止事件的默認動作,例如有時候我們會利用連結的<a>來當作按鈕,他本身DOM就擁有連結的功能,但是有時候我們會為他新增類似onclick的事件,而只要在該<a>觸發的事件中加入event.preventDefault(),就不會在執行他默認的動作,也就是不會再執行「連結到某個網址」這個動作,如下:
HTML

<a id="clickMe" href="https://ithelp.ithome.com.tw/articles?tab=tech">跳到鐵人幫幫忙</a>

JavaScript

document.getElementById('clickMe').onclick = () =>{
  console.log('跳頁的事件')
}

https://ithelp.ithome.com.tw/upload/images/20180829/201069354tUB6e8JxN.jpg
這時候雖然我們執行了事件,但是他還是會執行該DOM本身的功能,也就是跳轉網頁,所以會發現右方的跳到鐵人幫幫忙就不見了,但是console中有執行事件的過程,有時候我們會希望透過程式的判斷,希望他不要跳轉網頁,在程式中停止,就可以加入event.preventDefault()!我們在下方把他加進去!
https://ithelp.ithome.com.tw/upload/images/20180829/201069359StwUhHUUx.jpg
可以看到他就算點了也不會跳轉網頁!因為在事件中把該DOM預設功能給取消了!

以上這兩種方法都可以有效的去處理事件執行的狀態,但一般我們都常用return false;去結束某件事情,可惜的是return false並無法防止事件冒泡,只能取消DOM的預設功能,像下方的例子一樣:
https://ithelp.ithome.com.tw/upload/images/20180829/20106935WKoZKUbMnT.jpg

最後關於這三種停止事件的使用方法,在stackflow中有篇問答很熱烈的在討論,大家如果有興趣更深入的話可以看看,任意門在這裡,如果文章中有理解錯誤或講解不清楚的地方,還麻煩各位大大留言告訴我,我會盡快修正文章內容,謝謝大家的觀看/images/emoticon/emoticon41.gif

參考文章:

  1. http://www.w3school.com.cn/jsref/event_preventdefault.asp
  2. http://www.w3school.com.cn/jsref/event_stoppropagation.asp
  3. https://blog.csdn.net/sinat_27801935/article/details/75042940

2 則留言

7
fysh711426
iT邦研究生 4 級 ‧ 2018-08-29 02:32:33

事件冒泡是有趣的東西呢,可以優化事件的效能,
例如列表有 100 個項目,如果需要在每個項目都綁 click 事件,需要監聽 100 個事件,
而利用事件冒泡的特性將 click 綁在父元素上,
只需監聽 1 個事件,就能達到同樣的效果,
不過要小心,如果父子元素之間經過太多的節點,也會影響效能,
例如綁在 document 上。

雖然知道這件事,但好像沒有實戰過,還是習慣通通用 $('xxx').click() 解決。
/images/emoticon/emoticon16.gif

看更多先前的回應...收起先前的回應...

對哇!在某些時候也可以避免一些多餘的執行,哈哈!
大大是指在父元素觸發事件後,用event來判斷被點擊的子元素是什麼嗎/images/emoticon/emoticon19.gif

我現在比較少用Jquery了XD
不過在Jquery的執行環境中return false;好像就會幫忙執行stopPropagation()preventDefault()這兩個function/images/emoticon/emoticon13.gif
題外話是大大還真晚睡XD

Homura iT邦高手 1 級‧ 2018-08-29 11:36:36 檢舉

當大家都在爆肝學習
我已經在/images/emoticon/emoticon11.gif

fysh711426 iT邦研究生 4 級‧ 2018-08-29 18:52:12 檢舉

神Q超人
恩可以用 event.target 取得被點擊的項目,樓下 tacodrem 大大分享的文章有詳解。

自從用過 angular 就回不去了,哈哈哈,
Jquery 的 return false 這篇 有提到,的確兩者都會執行,
平常還真沒注意這些小細節。
/images/emoticon/emoticon13.gif

fysh711426 iT邦研究生 4 級‧ 2018-08-29 19:03:14 檢舉

Homura
神Q超人
哈哈哈,沒有爆肝學習...
昨天東摸西摸,睡前想說看一下 it 幫,
沒想到回完兩位大大的文章,就到這個時候了。
/images/emoticon/emoticon16.gif

fysh711426
大大不是準備跳槽Vue.js了嗎/images/emoticon/emoticon37.gif

Homura
我每天早上起床都非常之痛苦XD

4
tacodrem
iT邦新手 5 級 ‧ 2018-08-29 16:27:19

之前也有在研究冒泡事件的處理~
當時這篇文章讓我覺得超好用!!
提供一下XD
https://blog.techbridge.cc/2017/07/15/javascript-event-propagation/

看更多先前的回應...收起先前的回應...
fysh711426 iT邦研究生 4 級‧ 2018-08-29 18:28:03 檢舉

這篇講的好詳細!!

這篇真的很詳細!
看看他的在看看我的.../images/emoticon/emoticon16.gif

胡立大大的文章都很猛很厲害!!
都很深入淺出~!

神Q超人
別這樣說~光是願意打文章, 能夠打文章出來就很厲害了!!!
小弟還是潛水居多啊>"<

我已經把那篇部落格加進我的最愛了XD
歡迎常來分享心得啊!
一起交流一起變強!
/images/emoticon/emoticon69.gif

我要留言

立即登入留言