addEventListener 的第三個參數

addEventListener

2007 年我寫過一篇一樣標題的 addEventListener 的第三個參數,介紹了事件發生時, DOM Node 的 capture 和 bubbling,事隔十多年,前陣子定睛一看,發現 DOM spec 有變,第三個參數除了可以收 boolean 型別的 useCapture 之外,還可以收 options 物件,又稱為 EventListenerOptions,而這個 options 物件現在支援三個屬性,分別是:

  • capture-就是以前的第三個參數 useCapture,Boolean 型別。
  • once-新的選項,也是 Boolean 型別,用途就像是 jQuery 的 one 一樣,想不到現在也直接在 DOM 層原生支援了
  • passive-也是新選項,一樣是 Boolean 型別,用途是告訴瀏覽器,這個事件 handler function 會不會呼叫event.preventDefault來停止瀏覽器的原生行為,我最初其實是在 Google 的關於 scroll performance 的文件 看到的,就是如果你是 scroll event,以前會因為瀏覽器要判斷會不會被preventDefault,所以讓 scroll 的效能變差,加上這個選項可以直接告訴瀏覽器說沒有要 preventDefault 後,原生的事件行為就可以不管 event handler 直接處理了,如果裡面硬是執行event.preventDefault的話,那就會被忽略掉,然後根據使用的瀏覽器的話,有的會有警告訊息出現在 console。

Passive Event 的效果也有人做了影片可以看(來源):

EventListenerOptions 這個東西大概是在 2015 開始討論的,然後 2016 進到 WICG 討論,瀏覽器開始實做,一開始就是只有passivecaptureonce則是後來才加上的,所以可以看到 MDN 的瀏覽器支援度表格,once還要比較新一點的瀏覽器才支援,像是 Chrome 51 就支援passive,然後要到 55 才支援once,如果再仔細看,會發現最後一列是touchstarttouchmove事件如果是在 document 層的話,預設改為 passive 事件,這是 2017 年 Chrome 主導修改的行為,Firefox 也有跟進,主要就是希望能讓這些事件處理預設效能好一點,這部分的行為修改其實到現在都還沒標準化,目前還是在 WICG 那邊有個 open issue,除了 touch 事件外,其實連 document 層的 wheel 事件也在 Chrome 73,也就是現在的穩定版本也預設改為 passive 事件了,然後也是有 WICG 的 open issue,MDN 的表則是還沒有。

EventListenerOptions 也是有 polyfill 和工具 package 的,首先來說一下 polyfill 吧,我知道的有 dom4,其實搜尋一下還蠻容易找到其它的,不過差異沒很大,feature detection 的方式幾乎都是用 Object 的 getter 來看送進去的 options 物件的passive屬性有沒有被讀取過,有的話就表示瀏覽器有支援,然候 polyfill 其實也只有行為上的補完,不會真的讓效能提升,不過 polyfill 在現在的支援度下來看也是不太需要了。Package 的話有個 default-passive-events 會幫忙把 scroll、wheel、mouse、touch 等等有需要的事件都改為預設passive: true,如果是新專案先加一下似乎不錯,不過感覺上 Google 是很想都改掉的樣子,現在其實也只差 mouse 事件而已,應該是還怕影響太大不敢下手吧。


Lab Gradient

Gradient

一早起來就看到這篇文章 視覺上的完美漸層 Chromatic,介紹了一個 Sketch plugin 可以用不同色彩系統的漸層來產生更好的視覺效果,之前其實也有注意到這個問題好幾次,就是覺得 CSS gradient 的效果不好,也有注意到一些其他的漸層方法,不過一直沒記錄下來,所以趁這時候把一些資源記錄一下,該篇文章的作者 Samuel 是推薦 Lab 色彩系統的漸層。

目前因為 CSS 就是只有 RGB 漸層,所以要用其他系統的漸層就只能用模擬的,SASS 的話有 chromatic-sass,PostCSS 則是 postcss-easing-gradients,這套背後用的則是首篇文章也有介紹的 chroma.js 來轉換的,不過它其實主要是在做 easing gradient 的,然後還有一些線上的模擬工具可以讓人直接看看效果,第一個其實是 easing gradient 的工具,其實就是在 easing gradient 標準提案時有人做來讓人體驗的,另一個介面比較不 fancy,但是我覺得比較實用的 Lch and Lab colour and gradient picker


使用 VSCode 讀程式碼

VSCode peek window

偶爾看到些有趣的 library 會對它的原理和實做方式有興趣,就會花時間看看他們的程式碼,像是曾經介紹過的 immer,或是最近還在看的 lit-html,然後最近發現 VSCode 已經有把閱讀程式碼需要的功能都做好,而且因為原生對 JavaScript 支援很好,看 JavaScript 專案的時候很方便,不用特別安裝或設定什麼直接就可以開始。

閱讀程式碼其實也沒需要什麼特殊功能,就是看到不知道是什麼的東西(constant, variable, function, class ...)時,能不能快速移動到定義的地方,看完後還可以回到原處這類的 reference 和導覽的功能,在 VSCode 當中,這兩個功能就是F12移動到定義處和Ctrl+-移動回到上個位置,簡單一點的使用只要記得這兩個快速鍵就可以了,然後其實還有幾個進階的功能:

  1. Opt+F12Peek Definition,用 peek window 預覽定義,peek window 就是像上圖那樣一個浮在現在視窗上面的子視窗,通常右邊都會列出一些項目讓你可以挑選(peek),這個指令似乎也可以列出多個定義的位置,不過我還不確定是怎樣的情形會一個變數有多個地方定義它就是。
  2. Cmd+KF12Open Definition to the Side,這是兩段式的指令,先按Cmd+K然後再按F12,就會垂直分割出一個新視窗,然後新開的視窗就是所尋找的定義的程式碼。
  3. Shift+F12Peek References,這也是開 peek window,不過不一樣的點是它是列出專案內其他有用到這個東西的地方,有時候看定義不太理解可以直接看看怎麼使用,也還蠻有幫助的。

大概就這樣,Vim 的話其實也有內建的導覽功能,不過要產生對應的 reference 資訊還要些工具幫助,等研究研究後再來介紹嘍。


更之前的文章