教你應付一個很噁心卻常見的需求(點擊自身之外的區域關閉本身)

作前端最難受的就是產品給的需求以及測試給的bug了,看待這個標題是否是有點蒙,這是什麼需求,下面來解讀下!

需求

需求:以下圖,點擊已保存按鈕彈出已保存列表,當點擊屏幕其餘區域要關閉這個下拉框,是否是很簡單前端

加點東西,可是點擊這個下拉框內部的區域不能關閉下拉框)(原諒我裏面沒寫東西你就當有東西,給個機會噻!),是否是很常見,是否是很噁心!大家是怎麼作的。 以前我見過有人把事件掛在window上,而後把不想要操做dom都掛上class,而後在點擊事件裏面一一排除括弧笑,或者有人投機取巧在一部分dom上掛了事件,結果又是測試不是每次都能關閉,全看運氣!react

接天就來講下個人解決辦法,由於我是寫的react,我就直接上react代碼了,邏輯都是同樣,無妨!數組

掛載事件

首先在componentDidMount中寫下咱們函數的觸發:dom

window.addEventListener('click', (event) => {
      event = event || window.event;

        this.setState({
          savedListShow: false, // 這個是控制列表顯隱的狀態
        });
    })

事件掛在window上怎麼避免點擊列表內部的dom不會觸發呢,不要說什麼阻止冒泡,很差使的,首先咱們在事件中輸出咱們event,
看看究竟是什麼!函數

元素掛上不想觸發的識別class

這是我點擊列表內部輸出的event測試

說是路徑,其實在深一步輸出出來的是js對象,既然是js對象那咱們就能拿到對象上的calss屬性了,對於咱們的判斷也就不成問題了。this

去代碼中到找咱們不想要觸發的那個(或者是一堆)不想觸發的dom的最大父級,spa

對的我這裏是class爲SavedList的div,在最前邊(記住是最前邊)加上一個class _&saveBtn(別人不用的,省得衝突)。code

點擊事件中加判斷排除不想觸發的dom

在細看下上邊我點擊輸出的event中的path, 每個元素.後的就是class, 注意橫線處的class,這說明我點擊的事件源是我不但願觸發的區域,而後咱們回到最開始componentDidMount中的事件函數。component

componentDidMount() {
    // 點擊其餘區域關閉已保存條件彈窗
    window.addEventListener('click', (event) => {
      event = event || window.event;

      let isSaveStructure = event.path.some(item => {
      這裏使用了startsWith,相對來講比較嚴謹,這要是爲何強調要在最前邊添加的緣由了
        if (item.className && item.className.startsWith('_&saveBtn')) {
          return true;
        }
      });

      if (!isSaveStructure) {
        this.setState({
          savedListShow: false
        });
      }
    })
  }

這樣依賴咱們不想觸發的dom以及dom內部的元素,遇到這個點擊事件就會唄排除在外了,是否是很省心。

總結

  • 添加事件 window.addEventListener('click', (event) => {})
  • 在不想觸發的dom的最大父級上添加用於區分的class,好比classSavedList的div以及內部dom不須要觸發那就在SavedList上添加須要識別的class, 主要要避免和其餘人的衝突,最好是特殊一點;
  • 在以前寫好的實踐中,判斷注意path裏面的是一個數組,包含的是js對象,抓取返回回來的classNamestring類型,不是數組,咱們判斷使用的是startsWith();
相關文章
相關標籤/搜索