国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一個removeEventListener引發的思考

jeyhan / 2665人閱讀

摘要:而為對象時,可用選項如下之所以第三個參數有兩種形態,是在舊版本中只存在一個布爾值,即屬性但隨著時間推移以及發展的需要,需要支持設置更多的特性設置,所以有了選項這個對象傳參,又為了兼容以前的老程序,所以對兩者進行了兼容。

起因

最近在看以前的代碼時,發現年初在熟悉react hooks新特性時寫下了這樣一段代碼:

let i = 0;
function Test(props) {
  const { loading, error, startFetch } = props;
  useEffect(() => {
    const $btn = document.querySelector(".btn"); // .info-con 存在于外層的dom中
    $btn.addEventListener("click", () => {
      const action =`action data${i++}`;
      console.log("resbtn", action);
    }, false);
    return $btn.removeEventListener("click", () => {});
  });
  if (error) {
    return 
{error.msg}
; } return (
{loading &&

loading

}

finished

Saga模擬測試

); }

我用了addEventListener和removeEventListener來嘗試useEffect的掛載和清除功能,細心的你,發現這段代碼有幾個錯誤呢?
自我觀察,自認為是有如下幾個的:

清除函數使用方式錯誤,應該返回的是一個函數,like:() => { $btn.removeEventListener("click", () => {}); },而我這里是一個語句;

removeEventListener使用語法錯誤;

useEffect未使用第二個參數,導致addEventListener掛載會多次執行(可以優化)

第1個和第3個錯誤,是可以原諒的,當時自己對hooks還不熟悉。但第二個錯誤,是不可原諒的,這是需要檢討的。本文后面不會對useEffect做深入講解,官方文檔已經足夠清楚,后面圍繞removeEventListener來剖析。

認清removeEventListener

第二個錯誤,拆開看,又可分為兩個方面:removeEventListener使用方式多余與語法錯誤。

使用方式多余:雖然$btn添加了click監聽事件回調,但由于這個節點屬于當前Test組件,所以組件銷毀時,其相關節點的監聽事件也會一并銷毀,這個在自己剛接觸前端時就做過這一方面的解析,所以這里的removeEventListener使用是多余的。但如果換成一個組件外的節點,比如我后面替換的.info-con節點,這是一直存在于Layout組件中的,使用removeEventListener是必要的。

語法錯誤:指使用removeEventListener,前面兩個參數是必傳的,事件類型(type:click),事件回調函數(listener: callback),由于使用addEventListener是為事件添加的一個隊列(即同一個事件,可添加多個監聽回調),所以事件回調函數(listener)是必傳,且其引用與添加的事件監聽回調函數指向相同。詳細描述見官方文檔

關于語法錯誤,官方文檔中有這樣一段描述:

由于我在添加監聽時,使用的是箭頭函數,所以刪除時無法找到相同引用的監聽事件,所以第一件事就是改變監聽函數的寫法。完善后,寫法是下面這樣的:

let i = 0;
function Test(props) {
  const { loading, error, startFetch } = props;
  useEffect(() => {
    const $btn = document.querySelector(".info-con");
    const eventAction = () => {
      const action =`action data${i++}`;
      console.log("resbtn:", action);
    };
    $btn.addEventListener("click", eventAction);
    return () => {
      $btn.removeEventListener("click", eventAction);
    };
  }, []);
  if (error) {
    return 
{error.msg}
; } return (
{loading &&

loading

}

finished

Saga模擬測試

); }

到此,看似已經結束了。但既然已經打開了,就深入的學習一下這個api吧,常用的前兩個參數,我們都很熟悉,第三個參數寫成布爾值也偶爾會有,但是否已足夠了解呢?

第三個參數

addEventListener和removeEventListener傳參是一樣的,第三個可選參數都是一個對象或者一個布爾值:

target.addEventListener(type, listener[, options]);
target.addEventListener(type, listener[, useCapture]);
target.removeEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, useCapture]);

當參數為布爾值時,意指useCapture,是否在捕獲階段觸發監聽函數。而為對象時,可用選項如下:

clipboard.png
之所以第三個參數有兩種形態,是在舊版本中只存在一個布爾值,即useCapture屬性;但隨著時間推移以及發展的需要,需要支持設置更多的特性設置,所以有了options選項這個對象傳參,又為了兼容以前的老程序,所以對兩者進行了兼容。once和passive屬性非常有趣,但我還沒想到合適的使用它們的場景。查看官方文檔,發現里面確實有好多以前沒有關注到的東西,值得細細品味。
其實在js很多api中,我們都只用了一些常用的用法,而忽略了一些存在且也很適用的不常用傳參,比如下面這些:

setTimout(callback, time, ...params): 這個有多有用呢,有一道網紅面試題,關于閉包的,就可以利用這個參數來解決,在詳解網紅前端經典面試題:setTimeout與循環閉包提到過

    function test(){
         for (var i=0; i<5; i  ) {
            setTimeout( function timer() {
                console.log(new Date(),i);
            }, 1000);
        }
        console.log("end",new Date(),i);
    }

bind(thisArg, ...params): 為函數預先傳參,在react中用的比較多;

replace(reg, str | function): replace第二參數也可以為一個函數,用于自定義替換

split(reg, length): split其實也是有第二個參數的,用以指定返回數組的長度不超過指定大小;

暫時想不起來了...

思考

這一次關于對removeEventListener的使用錯誤,讓我不得不意識到,對于自己下一步技術提升的著重點還是該多關注基礎,不要學的太寬泛,而成為泛而不精的人,最后一無是處。最近這一年確實太癡迷(yilai)于框架(React),基礎關注的太少。框架與基礎,框架層出不窮,但基礎只是持續在演進。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106381.html

相關文章

  • Vue一個案例引發動態組件與全局事件綁定總結

    摘要:我們需要的最好效果肯定是當前的全局事件就在當前的組件下產生作用,當我們切換到其他組件時,事件自動刪除,于是我可能想到的就是利用鉤子函數去刪除這個全局事件。 最近在自學 Vue 也了解了一些基本用法,也記錄了一些筆記有興趣的朋友可以去查看我的其他文章,技術這東西真的不能光靠看,看是沒有的,你必須要動手實踐,只有在實戰項目中才能發現問題,才能發現我們沒有掌握的知識點,然后發現問題解決問題,...

    MycLambert 評論0 收藏0
  • 「讀懂源碼系列1」還在恐懼讀源碼?看完這篇就不怕了

    摘要:源碼真的這么可怕嗎從以上的事例中可以看出,其實并沒有。對于源碼的恐懼,讓我們漸漸思維固化,自己告訴自己不要去碰源碼,時間長了就遺忘了還有這樣一條路可走。 一個小需求 事情的起因,是昨天有一個新的需求被提出。 需求是要實現,讓我們自己定制的彈出層,具備按下 ESC 也能退出的功能。我把任務交給了同組的小伙伴S去實現。(這個項目用到了vue技術棧,以及餓了么的UI框架。) 我開完會回來,發...

    XGBCCC 評論0 收藏0
  • DOM事件總結(一)

    摘要:三級事件處理程序級事件定義了兩個方法,分別用于處理指定和刪除事件處理程序的操作和,他們都接收三個參數要處理的事件名作為事件處理程序的函數一個布爾值。布爾值如果是表示在捕獲階段調用事件處理程序,如果是表示在冒泡階段調用事件處理程序。 前言:擼完CSS-DOM緊接著來擼DOM事件,事件總結完成后我要開始總結動畫,然后用純JS實現一個輪播圖,前路漫漫,還有各種框架等著我~~~本篇主要內容有:...

    hedge_hog 評論0 收藏0
  • 從一次重寫原生方法遇到坑,總結一下Web中事件系統

    摘要:問題初探索刪掉那一點重寫的代碼后,表現符合預期了。每一次都重新造一個虛擬的,然后監聽其自定義事件,并且立即觸發這個自定義事件。真的不要隨便重寫原生方法。。。于是,我全面總結一下了中的事件系統,也算是對基礎的鞏固。 寫在前面 前段時間,我寫過一篇文章前端開發中的Error以及異常捕獲。 在文章中,我提到了這個問題: showImg(https://segmentfault.com/img...

    oysun 評論0 收藏0
  • JavaScript中一個運算符優先級問題引發思考

    摘要:中一個運算符優先級問題引發的思考題目假設已經聲明可定義為任何值。分析因為我們忽略了運算符的優先級。要知道,加號優先級高于三目運算,低于括號。為值,在里的判斷就是值。 JavaScript中一個運算符優先級問題引發的思考 題目 假設 val 已經聲明,可定義為任何值。則下面js代碼有可能輸出的結果為: console.log(Value is + (val != 0) ? define...

    zengdongbao 評論0 收藏0

發表評論

0條評論

jeyhan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<