模擬select,隱藏下拉列表的幾種實現

2022-07-12 07:42:10 字數 2680 閱讀 7414

平時開發過程中,出於各種原因模擬原生slect的要求並不算少見。

在實現的過程中,點選其他區域隱藏下拉列表,又是乙個必備的功能,

最近在一次開發的過程中引發了點思考,做下總結。

實際中的實現比較複雜,列表中還要增刪改查等操作。這裡就只放個最簡單的demo。

目的是點選select以外的其他區域,隱藏下拉列表。

效果大概這個樣子(簡單粗暴純演示用):

首先這確實不難實現,上來像方法一一樣擼袖子幹就完了

開始之前,先列下基本結構,待會好描述:

外層乙個warper,裡面是input,下面就是ul,li繫結點選事件。

// 點選列表,提示並隱藏彈框

clickhanler()

實現方式有下面這麼幾種:

這是原本比較熟悉和一直在使用的方式:

//元件掛載之後新增事件

componentdidmount()

})(this.idname)

document.addeventlistener('click', this.clicktriggerhandler)

}componentwillunmount()

}

至於如何判斷事件元素的歸屬也比較常見:

判斷當前元素的父元素是否為置頂元素,不滿足則迴圈上溯祖先元素,直到document。

/**

* 判斷是否屬於指定元素的子元素

* @param id 指定元素的標識

* @param dom 觸發事件的dom

*/const isparent=(id, dom)=> else

}// 最終返回false

return false;

}

這樣達到了我們的目的,不過是有些缺點的。

每次都溯源去判斷,效能消耗是個問題,特別是稍微複雜頁面,展示多個元件時。

假如有元素阻止了冒泡,如果點到了這個元素,那麼全域性就監聽不到該事件了。

}>測試
那麼效果就如下圖所示了:

此外實現方式總感覺不夠優雅,所以我們應該考慮其他實現方式。

可能一開始思維固話之後,就不太好轉變,因為上面的方式是一直所熟悉的,一時想不到其他方法。

這時候可以去跟別人交流一下(這裡的交流包括但不限於老司機面談,搜尋某種實現思路,優秀開源框架)。

得到了另乙個方向:點選其他區域的時候,意味著當前區域失去了焦點,

基於這一點可以從input操作了。

}

onblur=}

>

這樣看起來很美好,但是點選列表的時候,直接關閉了,沒有執行this.clickhanler**。

因為下拉列表操作點選的時候,其實對於input而言也是失去焦點。

所以先執行了input的onblur,隱藏列表,state更新之後,

列表的click操作並沒有得到相應。

既然是執行順序的問題,那麼我們可以有下面兩種解決思路:

既然blur執行順序在前,重新渲染後會影響後續執行,那麼我們將blur事件的**延遲執行,即不立即去setstate,那麼li的click事件就會執行,然後再去隱藏列表。

至於如何延遲執行,顯然就是我們的萬能settimeout了:

}

onblur=}

>

這樣可以滿足我們的需求,此外還有另一種方式

// 這裡也順便解釋了下問題出現的原因

mousedown->blur->mouseup->click

既然click觸發時機晚於blur,那我們換成mousedown不就繞過去了。

}

onblur=}

>

// 列表的選擇**在mousedown時執行

效果同上,這裡就不重複放圖了。

如果我們的目的是點選列表的時候,完全不觸發blur事件,可以在clickhanler**裡加上event.preventdefault(),這樣就不會按照原來的順序出發blur事件了。例如這裡:

// 本身自行處理了列表顯示,就不用呼叫blur事件了

clickhanler(event)

具體是否阻止預設事件,就看具體應用了,示例**這裡就沒有阻止預設事件,

而是將列表的顯示隱藏全交給焦點事件來處理。

// 只關注點選的邏輯,公共邏輯交給blur統一管理

clickhanler()

即點選其他區域時,點選的是背景mask,交給他來統一處理。

因為這樣點選存在乙個比較明顯的問題,如果想要點選其他元素例如radio時,需要二次點選。

所以這裡就不去折騰這種實現了。

瀏覽器點選螢幕事件觸發順序

eagle-ui

本文是自己的一篇學習總結記錄,不過我感覺最有用的還是對自己的觸動。因為平時都習慣於第一種方式去實現功能,特別是在業務開發過程中,第一選擇肯定是自己常用的。還是在空閒時候才有心情去優化。

這時候才清晰的理解我們所謂的讀優秀開源作品原始碼,學習的是什麼,不要為了讀原始碼而讀原始碼,有目的有思維的讀才能學習更多。望諸君共勉,再次對參考文章表示感謝。

JS模擬select下拉列表

doctype html html lang en head meta charset utf 8 title js模擬select下拉列表 title style body emul box select arrow sub sub li sub li hover sub li.hover sty...

jquery操作下拉列表select

jquery獲取select選擇的text和value 語法解釋 1.select id change function 為select新增事件,當選擇其中一項時觸發 2.var checktext select id find option selected text 獲取select選擇的tex...

js控制select 下拉列表

通過js控制select下拉列表 通過js獲取select下拉列表的值class form control 1option events 利用以下函式,可以取到被選中的option的位 getselected function 或利用此函式可以獲取被選中的option的值 getselected f...