2022年1月20日 星期四

JavaScript : removeEventListener 無法移除事件

2022年1月20日 星期四

JavaScipt 中可以使用 addEventListener 來為某事件設定要執行的程序,例如為了讓我的 HTML5 程式在行動載具上操作時,不會「滑來滑去」,我加了底下兩行:


document.addEventListener('touchstart', function(e){ e.preventDefault(); }, { 'passive' : false });
document.addEventListener('touchmove', function(e){ e.preventDefault();}, { 'passive' : false });


改變了在 document 的按下跟移動時的預設動作。

因為平常都是開了就進入我的程式,不用了就關掉,不會影響其它程式的運作。最近試著讓我的程式嵌入 Blogger 中使用,不使用了,可以按一個按鈕關掉我的程式,回到 Blogger 中繼續其它操作。前述的流程在 Windows 的 Chrome 中看似沒問題,但是在行動載具上就出事了!

因為上面兩行程式是改變 touchstar 和 touchmove 的動作,對行動載具有影響,電腦上則是使用 mousedown 和 mousemove,最近都是在電腦上測試難怪我一直沒發現有問題。

好啦!知道在結束我的程式以後,在 Blogger 不能按畫面的原因了,就利用「removeEventListener」把 document 的 touchstart 和 touchmove 事件刪掉不就好了嗎?

試了好久,答案是不行!

話說冤有頭,債有主,在使用 removeEventListener 時,必須指定是哪一種事件,原來綁定到什麼程序、參數,都必須吻合才能移除該項。而我原來並沒有指明 function 的名稱,即使我把原來 add 時的程再指定給它,也不是原來的了。

使用 anoymous function 時

也因為這樣,我的程式沒有清除加入的那兩道,嵌入 Blogger 中,我的程式未徹底清乾淨,再度載入時,又新增兩項進去,沒有重新整理頁面的情形下,垃圾就愈積愈多,天知道會出什麼事。

那如何解決 removeEventListener 失敗的問題呢?

問題在使用了 anoymous function,那就把 function 先定義好,再讓 addEvenListener 用:


prventDefautHandler = function(e){ e.preventDefault(); };
document.addEventListener('touchstart', prventDefautHandler, { 'passive' : false });
document.addEventListener('touchend', prventDefautHandler, { 'passive' : false });


像 HTML5 Lotto 這支改完就變這樣的結果:

name: "prventDefaultHandler"

「有名有姓」以後,要追債就比較好辦了,想移除就執行:


document.removeEventListener('touchstart', prventDefautHandler, { 'passive' : false });
document.removeEventListener('touchend', prventDefautHandler, { 'passive' : false });


記得之前如果有設定別的參數,參數不同時,也一樣無法順利移除。哈哈哈~只能說 removeEventListener 真嚴格,一個小細節都不能錯,不然它就不理你了!

觀察了前的的畫面後,也發現,在 LimeJS  的 director.js 中有新增 resize 和 orientationchange 的事件,所以我也順便在篏入 Blogger 的程式結束時加入了清除的指令:


var vsm = goog.dom.ViewportSizeMonitor.getInstanceForWindow();
goog.events.removeAll(vsm);
goog.events.removeAll(goog.global);


果然遺留下來的垃圾就都沒有了。


1 則留言:

  1. 沒錯,要用有名字的function
    我之前也煩惱過這個問題XD

    回覆刪除

 
雄::gsyan © 2009. Design by Pocket