1. 程式人生 > >如何獲取事件冒泡裡最頂層的元素(或者任意層的元素)

如何獲取事件冒泡裡最頂層的元素(或者任意層的元素)

先舉個例子,有如下DOM結構:

    <ul @click="toApply">
              <li data-user-id="1">  
                  <img src="/static/user/face/4.jpg" class="user">
                  <div class="info">
                     <p class="name">ThreeTree</p>
                     <p class="intro">
                         <span class="man">19</span>
                         大哥 想請教一個問題 
                      </p>
                     <p class="from">來自:JS討論群</p>
                     <button class="agree">同意</button>
                  </div>
              </li>
              <li data-user-id="2">  
                  <img src="/static/user/face/6.jpg" class="user">
                  <div class="info">
                     <p class="name">rshu</p>
                     <p class="intro">
                         <span class="man">19</span>
                         我是rshu
                      </p>
                     <p class="from">來自:QQ群-ThinkPHP技術討論中心</p>
                     <button class="other">已拒絕</button>
                  </div>
              </li>
              <li data-user-id="3">  
                  <img src="/static/user/face/7.jpg" class="user">
                  <div class="info">
                     <p class="name">雲端之上</p>
                     <p class="intro">
                         <span class="man">19</span>
                         你是騰訊的?
                      </p>
                     <p class="from">來自:臨時會話</p>
                     <button class="other">已拒絕</button>
                  </div>
              </li>
              <li data-user-id="4">  
                  <img src="/static/user/face/8.jpg" class="user">
                  <div class="info">
                     <p class="name">後知後覺</p>
                     <p class="intro">
                         <span class="man">19</span>
                         請求加為好友
                      </p>
                     <p class="from">來自:JS討論群</p>
                     <button class="other">已同意</button>
                  </div>
              </li>
              <li data-user-id="5">  
                  <img src="/static/user/face/9.jpg" class="user">
                  <div class="info">
                     <p class="name mes">阿里巴巴社招內推</p>
                     <p class="message">已傳送驗證訊息</p>
                     <button class="other">等待驗證</button>
                  </div>
              </li>
       </ul>

渲染結果如下圖:


現在我的需求是點選每個LI裡面的任何區域,都會根據LI的data-user-id屬性跳轉到各自的好友申請頁面。顯然我是不會直接在LI上繫結事件的,因為那樣會造成瀏覽器的效能下降。更優的做法是在LI的父元素上繫結事件,也就是事件代理(或者說事件委託),事件代理原理是通過事件冒泡,點選LI元素,那麼LI的父元素ul也會觸發click事件,這樣效能就得到了極大的提升。

但是,現在問題來了,我通過let target=e.target||e.srcElement來獲取目標元素,獲取到的target就可能是img,可能是p,可能是div,也可能是span,button。在這些子元素上是沒有

data-user-id屬性的,這個屬性唯獨LI元素才有。也就是說,我只有拿到LI元素,才能獲取data-user-id屬性,不然是跳轉不到好友申請頁面的。

那怎樣獲取LI元素呢?這其實就是經典的獲取事件冒泡裡任意層指定的元素的問題,現在我提供一種完美的解決方案,可以獲取任意層的父元素。

toApply方法如下:

 toApply(e){
      let target=e.target||e.srcElement   // ES6的語法,用let宣告一個變數
      while(target.tagName!='LI'){
        target=target.parentNode?target.parentNode:''  //不斷取父節點來替換target
      }
      if(target) {   //如果目標元素LI存在
        const user_id=$(target).attr('data-user-id')
        this.$router.push({   //這是vue2.0的語法,跳轉到指定頁面
          path: '/friendApply',
          query: {user_id: user_id} 
        })
      }
 }
我通過一個while迴圈,來不斷地取target的父元素,直至target為父元素LI為止,取到後再跳轉到各自的好友申請頁面。這樣問題就完美解決了。

總結:專案中遇到的坑,很多時候只要加以思索就可以解決。只有想不到,沒有做不到。