在Jquery中on()方法作事件委託是很是方便的。在vue中數據和視圖分離,不須要像jquery那樣頻繁操做dom元素,因此在vue中引入jquery庫就不是那麼必要。可是有時候咱們依然須要作事件代理,下面用原生js來封裝一個事件代理的全局方法:vue
以前看到其餘博客上提供的方法(這種方法並不合適):jquery
在父元素上綁定點擊事件dom
<div class="panel" @click="rowClick1($event)"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <a href="#"></a> </div>
這樣來實現:使用e.target能夠得到點擊時獲取的全部屬性與值,咱們能夠經過e.target.localName獲取點擊的標籤名,來進行對比判斷,相同則觸發綁定事件spa
<script> rowClick1(e){ console.log(e.target); if(e.target.localName === 'li'){ console.log("觸發事件1"); }else if(e.target.localName === 'a'){ console.log("觸發事件2"); } } </script>
不足之處: 例如在此例中 假如 li標籤中還有子元素,例如li中有一個span標籤,當鼠標點擊到li中的span時,此時的 e.target 是li的子元素span, 語句: if(e.target.localName === 'li'){ console.log("觸發事件1"); } 不能知足需求代理
下面是我改進的方法:code
<div class="panel" @click="rowClick1($event)"> <li>1<span>我是span標籤</span></li> <li>2<span>我是span標籤</span></li> <li>3<span>我是span標籤</span></li> <li>4<span>我是span標籤</span></li> <a href="#" ><span>我是span標籤</span></a> </div>
實現方法:e.path 是事件觸發點上冒泡所通過的全部dom元素, e.currentTarget.querySelectorAll(selector) 經過父元素找到 須要委託事件的元素,判斷dom對象相同,觸發事件orm
<script> rowClick1(e){ var tagArr = e.currentTarget.querySelectorAll('li') var elArr = e.path var flag = true; for(var i=0;i<tagArr.length;i++){ var tagEl = tagArr[i] for(var j=0;j<elArr.length;j++){ if(tagEl === elArr[j]){ callback(elArr[j]); } if(e.currentTarget === elArr[j]){ flag = false; break; // 循環到父元素時,終止循環,由於咱們只須要爲處理委託掛載點的子元素 } } if(!flag){ break; } } } </script>