JS中的事件委托(事件代理)
一步一步来说说事件委托(或者有的资料叫事件代理)
- js中事件冒泡我们知道,子元素身上的事件会冒泡到父元素身上。
- 事件代理就是,本来加在子元素身上的事件,加在了其父级身上。
- 那就产生了问题:父级那么多子元素,怎么区分事件本应该是哪个子元素的?
- 答案是:event对象里记录的有“事件源”,它就是发生事件的子元素。
- 它存在兼容性问题,在老的IE下,事件源是 window.event.srcElement,其他浏览器是 event.target
- 用事件委托有什么好处呢?
- 第一个好处是效率高,比如,不用for循环为子元素添加事件了
- 第二个好处是,js新生成的子元素也不用新为其添加事件了,程序逻辑上比较方便
--------------------
好吧,下面还是用例子来说,更容易理解。
---------------------
例子1. 页面有个ul包含着4个li,鼠标移动到li上,li背景变成红色,移出,背景恢复原色。
如果按照以前的写法,代码如下:
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul> <script type="text/javascript">
window.onload = function(){
var oUl = document.getElementById('ul1');
var aLi = oUl.children;
console.log(aLi); //传统方法,li身上添加事件,需要用for循环,找到每个li
for (var i=0;i<aLi.length;i++) {
aLi[i].onmouseover = function() {
this.style.background = 'red';
}
aLi[i].onmouseout = function(){
this.style.background = '';
}
}//for结束 }
</script>
现在用事件委托的方式,onmouseover、onmouseout方法要加在ul身上了,再通过找事件源的方式,改变li背景,代码如下:
上面ul的html代码不变,js部分变为
<script type="text/javascript">
window.onload = function(){
var oUl = document.getElementById('ul1');
oUl.onmouseover = function(ev){
var ev = ev || window.event;
var oLi = ev.srcElement || ev.target;
oLi.style.background = 'red';
} oUl.onmouseout = function(ev){
var ev = ev || window.event;
var oLi = ev.srcElement || ev.target;
oLi.style.background = '';
} }
</script>
效果如下:

但是会发现,鼠标移到了ul身上而不是某个li身上时,获取的事件源是ul,那么整个ul背景将变红,这不是想要的结果,怎么办?
答曰:加个判断。通过事件源的nodeName判断是不是li,是才做出反应,不是不理它。为了防止nodeName在不同浏览器获取的字母大小写不同,加个toLowerCase()
所以,上面的js代码更改如下:
<script type="text/javascript">
window.onload = function(){
var oUl = document.getElementById('ul1'); oUl.onmouseover = function(ev){
var ev = ev || window.event;
var oLi = ev.srcElement || ev.target;
if(oLi.nodeName.toLowerCase() == 'li'){
oLi.style.background = 'red';
} } oUl.onmouseout = function(ev){
var ev = ev || window.event;
var oLi = ev.srcElement || ev.target;
if(oLi.nodeName.toLowerCase() == 'li'){
oLi.style.background = '';
}
} }
</script>
效果如下很完美:

这就是不用for循环写一堆了,下面再来说说第二个好处:js新生成的子元素也不用新为其添加事件了,程序逻辑上比较方便
上面的文件,假如我再新添加个按钮,点击按钮,ul里就新增加个li,如果用传统的方法,for循环为li添加事件,问题就出现了,最开始有的4个li是有onmouseover和onmouseout事件的,但是后来动态生成的li里没有这两个事件处理函数,因为for循环的时候它还没生成。怎么办呢?只能在按钮点击后,生成li,然后再为生成的li再绑定事件,真是麻烦的很。而事件委托的方式就没事,当后来动态生成的li出现的时候,不用做改变,移到它身上,还是变色的,因为事件是绑定在ul身上的。
新浪微博里,当你发一条新微博出去,发出去的信息在页面上显示,鼠标移动到新发的信息的人头像上时,依然会有很多事件,如果用原来的方式,就要做很多处理,事件委托的话,就很方便了!
JS中的事件委托(事件代理)的更多相关文章
- Js 中的事件委托/事件代理
什么叫事件委托/事件代理呢 ? JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件. 事件冒泡: 当事件发生后,这个事件就要开始传 ...
- JavaScript中事件委托(事件代理)详解
在JavaScript的事件中,存在事件委托(事件代理),那么什么是事件委托呢? 事件委托在生活中的例子: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托 ...
- python 全栈开发,Day55(jQuery的位置信息,JS的事件流的概念(重点),事件对象,jQuery的事件绑定和解绑,事件委托(事件代理))
一.jQuery的位置信息 jQuery的位置信息跟JS的client系列.offset系列.scroll系列封装好的一些简便api. 一.宽度和高度 获取宽度 .width() 描述:为匹配的元素集 ...
- 理解js事件冒泡事件委托事件捕获
js事件冒泡 javascript的事件传播过程中,当事件在一个元素上出发之后,事件会逐级传播给先辈元素,直到document为止,有的浏览器可能到window为止,这就是事件冒泡现象. <di ...
- js中的点击事件(click)的实现方式
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- jQuery---jQ动画(普通,滑动,淡入淡出,自定义动画,停止动画),jQuery的事件,jQ事件的绑定/解绑,一次性事件,事件委托,事件冒泡,文档加载
jQuery---jQ动画(普通,滑动,淡入淡出,自定义动画,停止动画),jQuery的事件,jQ事件的绑定/解绑,一次性事件,事件委托,事件冒泡,文档加载 一丶jQuery动画 show,hide, ...
- JS中的事件委托/事件代理详解
起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...
- js 事件委托 事件代理
JavaScript高级程序设计上解释:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件. 通过例子类比: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三 ...
- JS事件委托(代理)学习笔记
在开始之前我们先来熟悉一下HTML DOM addEventListener()方法,该方法用于向指定元素添加事件句柄.语法说明如下图所示: 主要想强调一下第三个参数useCapture,默认值为fa ...
- JS中的异步以及事件轮询机制
一.JS为何是单线程的? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊.(在JAVA和c#中的异步 ...
随机推荐
- Android-PickerView【仿iOS的PickerView控件,并封装了时间选择和选项选择这两种选择器】使用
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本文主要演示Android-PickerView的选项选择器.时间选择器的简单运用.由于每一个版本略有不用,所以实际使用方式以git ...
- docker-compose-volumes的说明
docker-compose里两种设置方式都是可以持久化的 绝对路径的 ghost: image: ghost volumes: - ./ghost/config.js:/var/lib/ghost/ ...
- 实例分析C程序运行时的内存结构
先验知识 静态变量存储在静态存储区,局部变量存储在动态存储区(栈),代码存放在代码区 寄存器,EBP指向栈底,ESP指向栈顶,EIP指向正在执行指令的下一条指令,三个寄存器中保存的都是地址,32位 ...
- Window环境下搭建Git服务器
如果公司要搭建自己的 Git 服务器,可以使用 gitblit 这个开源的 Git 服务器 下载gitblit安装包 到 http://gitblit.com/下载安装包 解压缩下载的压缩包即可,无需 ...
- AppBoxFuture(五): 分布式文件存储-Store Everything
本来本篇是想介绍前端组件化开发用户界面,发现框架还未实现文件存储,原本计划是后续设计开发的,索性把计划提前,所以本篇将介绍基于Raft实现分布式的文件存储引擎. 一. 实现思路 既然是分布式存 ...
- 查询拼接SQL语句,多条件模糊查询
多条件查询,使用StringBuilder拼接SQL语句,效果如下: 当点击按钮时代码如下: private void button1_Click(object sender, EventArgs e ...
- Ext.isNumber与Ext.isNumeric
Ext.isNumber: Ext.isNumber(1) true Ext.isNumber(new Number(1)) false Ext.isNumber("1") fal ...
- ajax和axios、fetch的区别
参考文章: https://www.jianshu.com/p/8bc48f8fde75 Fetch API是新的ajax解决方案,用于解决古老的XHR对象不能实现的问题. fetch是用来取代传统的 ...
- 性能测试 基于Python结合InfluxDB及Grafana图表实时监控Android系统和应用进程
基于Python结合InfluxDB及Grafana图表实时监控Android系统和应用进程 By: 授客 QQ:1033553122 1. 测试环境 2. 实现功能 3. 使用前提 4. ...
- 七、Android动画
Android的动画可以分为三种:View动画.帧动画和属性动画,帧动画也属于View动画的一种,只不过它和平移.旋转等常见的View动画在表现形式上略有不同而已. 1.View动画 平移动画:Tra ...