一步一步来说说事件委托(或者有的资料叫事件代理)

  1. js中事件冒泡我们知道,子元素身上的事件会冒泡到父元素身上。
  2. 事件代理就是,本来加在子元素身上的事件,加在了其父级身上。
  3. 那就产生了问题:父级那么多子元素,怎么区分事件本应该是哪个子元素的?
  4. 答案是:event对象里记录的有“事件源”,它就是发生事件的子元素。
  5. 它存在兼容性问题,在老的IE下,事件源是 window.event.srcElement,其他浏览器是 event.target
  6. 用事件委托有什么好处呢?
  7. 第一个好处是效率高,比如,不用for循环为子元素添加事件了
  8. 第二个好处是,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中的事件委托(事件代理)的更多相关文章

  1. Js 中的事件委托/事件代理

    什么叫事件委托/事件代理呢 ? JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件.   事件冒泡: 当事件发生后,这个事件就要开始传 ...

  2. JavaScript中事件委托(事件代理)详解

    在JavaScript的事件中,存在事件委托(事件代理),那么什么是事件委托呢? 事件委托在生活中的例子: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托 ...

  3. python 全栈开发,Day55(jQuery的位置信息,JS的事件流的概念(重点),事件对象,jQuery的事件绑定和解绑,事件委托(事件代理))

    一.jQuery的位置信息 jQuery的位置信息跟JS的client系列.offset系列.scroll系列封装好的一些简便api. 一.宽度和高度 获取宽度 .width() 描述:为匹配的元素集 ...

  4. 理解js事件冒泡事件委托事件捕获

    js事件冒泡 javascript的事件传播过程中,当事件在一个元素上出发之后,事件会逐级传播给先辈元素,直到document为止,有的浏览器可能到window为止,这就是事件冒泡现象. <di ...

  5. js中的点击事件(click)的实现方式

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  6. jQuery---jQ动画(普通,滑动,淡入淡出,自定义动画,停止动画),jQuery的事件,jQ事件的绑定/解绑,一次性事件,事件委托,事件冒泡,文档加载

    jQuery---jQ动画(普通,滑动,淡入淡出,自定义动画,停止动画),jQuery的事件,jQ事件的绑定/解绑,一次性事件,事件委托,事件冒泡,文档加载 一丶jQuery动画 show,hide, ...

  7. JS中的事件委托/事件代理详解

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  8. js 事件委托 事件代理

    JavaScript高级程序设计上解释:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件. 通过例子类比: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三 ...

  9. JS事件委托(代理)学习笔记

    在开始之前我们先来熟悉一下HTML DOM addEventListener()方法,该方法用于向指定元素添加事件句柄.语法说明如下图所示: 主要想强调一下第三个参数useCapture,默认值为fa ...

  10. JS中的异步以及事件轮询机制

    一.JS为何是单线程的? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊.(在JAVA和c#中的异步 ...

随机推荐

  1. 【Android Studio安装部署系列】二十七、Android studio修改项目名称和包名

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 实际项目开发中可能碰到项目名称写错了或者需要修改,而且包名可能也想要修改,那么如何操作呢. 本文是在Android Studio3. ...

  2. 麒麟子Cocos Creator实用技巧一:如何正确地显示微信头像

    不管是游戏App,还是H5,又或者是微信小游戏.但凡接入了微信登录的应用,都可能需要显示微信头像. 在Cocos Creator中,我们常见的显示方法像下面这样 var headimg = 'http ...

  3. Activiti(一) activiti数据库表说明

    activiti介绍: activiti是一个业务流程管理(BPM)框架.它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩展的可执行流程语言框架.开发人员可以通过插件直接绘画出 ...

  4. :only-child和:only-of-type选择器的比较

    :only-child 当元素是唯一的子元素,被选择. HTML代码: <body> <div class="x"> <div>第一个DIV&l ...

  5. vue element-ui 分页组件封装

    <template> <el-pagination @size-change="handleSizeChange" @current-change="h ...

  6. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

  7. 360浏览器兼容模式下IE内核版本

    问题 最近在跟客户演示系统时,自己电脑IE 11下好好的,我们web系统最低支持到IE9.在客户电脑上,IE9浏览器下可以正常浏览,但是360兼容模式下,页面什么也不显示. 通过F12调试工具发现,3 ...

  8. 微信分享大图遇到的问题(Android)

    起因: 要做一个微信图片分享的功能,但是对于大图会如下问题: 当时没有仔细查看错误日志,单纯的以为是图片太大的问题. 分享图片代码: public void WXsharePic(String tra ...

  9. 浅谈Flutter(一):搭建Flutter开发环境

    学习内容来自: Flutter中文网  . Flutter实战 -------------------------------------------------------------------- ...

  10. Linux下使用yum安装软件命令

    1.yum list | grep 要下载的文件名字2.yum install 完整文件名字3.rpm -qa | grep 软件名字 //查看版本