如何获取事件冒泡里最顶层的元素(或者任意层的元素)
2017-06-30 13:03
274 查看
先举个例子,有如下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为止,取到后再跳转到各自的好友申请页面。这样问题就完美解决了。
总结:项目中遇到的坑,很多时候只要加以思索就可以解决。只有想不到,没有做不到。
<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为止,取到后再跳转到各自的好友申请页面。这样问题就完美解决了。
总结:项目中遇到的坑,很多时候只要加以思索就可以解决。只有想不到,没有做不到。
相关文章推荐
- Kivy A to Z -- 如何在Kivy中获取SD卡或者U盘的插拔事件
- 绑定在标签中的事件如何获取当前元素
- W3C下的冒泡和捕获机制。到底是冒泡呢。还是捕获呢。一个DOM元素绑定多个事件时如何执行。
- 原生JS如何利用冒泡减少事件的触发,只代理给共有的父元素。
- 如何给元素添加事件监听和取消事件冒泡
- W3C下的冒泡和捕获机制。到底是冒泡呢。还是捕获呢。一个DOM元素绑定多个事件时如何执行。
- 如何获取父元素下的最后一个子元素或者第一个子元素
- jQuery如何获取div距离窗口顶部或者父元素顶部的距离,jquerydiv
- 如何用JS获取元素某一事件上绑定的所有Listener
- ScrollView里嵌套ListView,如何禁用ListView的滚动事件,或者触发ListView滚动时调用父元素ScrollView的滚动事件?
- W3C下的冒泡和捕获机制。到底是冒泡呢。还是捕获呢。一个DOM元素绑定多个事件时如何执行。
- Javascript调试的小窍门: 如何获取元素上的事件绑定函数?
- jquery如何获取事件_冒泡
- 如何获取ie窗口中用户点击最小化事件?
- Flex中如何通过监听focusIn和focusOut事件,在通过displayAsPassword属性固定密码格式显示文本框获取焦点时显示文本
- 如何用javascript获取文本框,下拉框,单选框的对应值或者将值赋给它们
- Javascript 阻止javascript事件冒泡,获取控件ID值
- 如何用javascript获取文本框,下拉框,单选框的对应值或者将值赋给它们?
- JS获取触发事件元素的方法
- Flex中如何用getItemAt事件和数组访问操作符[]从ArrayCollection中获取数据显示的例子