使用 MutationObserver 監視DOM的背景更新,經驗筆記
前情提要
這次在專案上使用了sveltekit 作為前端框架,UI則是用bootstrap, 在列表頁的時候需要每5秒更新(圖1),取得最新的生理資訊。
![]() |
| 列表頁(圖1) |
![]() |
| Network背景資源(圖2) |
主想法
為了減少資源耗損,當按下「檢視」打開彈窗(modal)的時候,背景更新可以先暫時,畢竟彈窗(modal)會佔據整個版面,focus都會在彈窗上,等彈窗(modal)關閉後 再繼續執行背景更新。(圖3)
![]() |
| 彈窗開啟(圖3) |
實際作法
如果要觀測彈窗(modal),就會需要動態監測dom的變化(圖4) , 需要觀察 modal-open,是否有開啟。
![]() |
| 動態監測dom(圖4) |
在做法上使用了MutationObserver 來監視dom的變化,當監測到 body 的class 出現了.modal-open,代表彈窗已開啟,就可停止背景更新。(圖5)
![]() |
| MutationObserver監視.modal-open(圖5) |
切換到了B頁→A頁,B的背景更新並不會停止;從A頁→C頁 ,A頁的背景更新並不會停止(圖6) ,也就表示 背景更新不會隨著切換頁面而停止。主要是因為在同一個SPA的特性,頁面不重載,DOM並沒有銷毀。
填坑--解決方法
加入了writeable 動態的背景更新「開關管理」,更新writeable的狀態,搭配$ 動態的讀取資料狀態的變化,類似redux的狀態管理。因為用的modal在每頁都是相同的,並不會因為切換頁面造成dom重新渲染,所以監測也並不會因為切換頁而消失。
設立了一個$modalObserver='',當彈窗(modal)開啟才給值 $modalObserver=0,關閉$modalObserver=1
$modalObserver 就可讀取到到最新的modal狀態,進而去執行該頁的背景更新,也就能避免累加的背景更新。(圖7)
當在A頁開啟modal的時候,就執行A頁的背景更新;當在B頁開啟modal的時候,就執行B頁的背景更新......依此類推。
當在A頁開啟modal的時候,就執行A頁的背景更新;當在B頁開啟modal的時候,就執行B頁的背景更新......依此類推。
| 加入writeable,共管各頁的modal狀態(圖7) |
心得
這次的專案背景更新並不會因為切換頁就停止,SPA的特性也真是讓我學到很多。
以往傳統的方法,寫個location.href='指定頁',整個js 和dom 就會重新執行。
但使用了svelte後,只要這個dom還在,當物件有重複呼叫modal後,上次的資料是還會留存的。
使用writeable真的需要特別留意,之前在做換頁的時候把page綁在writeable上,只要writeable的page換頁有變動api就去執行,但也造成點選換頁越多api就執行越多次,摸了老半天一直找不到原因😅,最後只好打掉重練。
這次的經驗,writeable 更適合用在動態的狀態管理,透過最新的狀態在進而去做下一步。






留言
張貼留言