从事件冒泡到事件委托,进而实现动态绑定事件

来源:互联网 发布:办公楼网络改造方案 编辑:程序博客网 时间:2024/06/05 17:07

原文链接:http://xpzheng.jsp.fjjsp.net/blog/2017/03/19/10024

事件冒泡的机制可以实现“事件委托”,这可能是事件冒泡最大的优点了,之前在一篇文章中介绍了事件冒泡的原理和优缺点,戳这里去看:js事件冒泡的原理及解决办法

“事件委托”,简单解释就是将A将要发生的事件委托给B,每次A事件要触发的时候都会“问候”一下B,B会告诉A具体的事件执行方法。

介绍了“事件委托”的概念,下面来看一个矛盾:

由于JavaScript是命令式的语言,它不能像CSS一样,当添加了一个新的元素,给它标注上相应的类名,它就能像“魔法盒子”一样自动给自己各种加特效。JavaScript对于新添加的元素是很无力的,因为元素在运行的过程中被添加,所以JavaScript并不能动态感知到新元素的添加,然后为其添加相应的“行为”,这样就导致了即便你给当前要添加的元素添加了对应的类名,也不能保证它像其他拥有相同类名的元素一样有同样的事件处理。

了解了这个“矛盾”后,我们不妨试着找出解决矛盾的方法,既然JavaScript无法感知新添加的元素(也就是说即便你为其它与该元素相同的元素添加了事件,也无法应用到该元素下),那么我们是否可以将事件交托给没有被新添加的元素上,并且保证该元素永远不会“消失”,这样事件发生在这个被委托的对象上,我们再通过一定的“手段”,得到真正触发该事件的元素,这样不就实现了动态绑定事件了吗?

重新梳理一下思路,让我们总结一下动态绑定事件的操作流程:

1)将事件绑定在一个存在且不会“消失”的元素上,假设这个元素是文档对象document2)当位于文档对象下层的元素触发这个事件(如点击一个按钮)时,由于事件冒泡机制的存在,必定会一直向上冒泡,直到最终的document对象3)由于document是绑定了事件了的,在该事件内找到真实的触发元素(点击了按钮,而不是点击了文档),进而操作这个真实的触发对象4)当新添加元素的时候,该元素是没有事件绑定的,但是一旦进行某些操作(鼠标进入,点击,双击等),这些操作最终都会反应到document上,然后再进行第3)步,就轻而易举得实现了“动态绑定”事件了

上述流程暴露了一个问题:如何由document的事件处理函数得到真实触发该事件的对象?有两种方法:

1)通过事件处理函数的event对象的target属性得到真实触发该操作的元素,注意该操作返回的是一个DOM对象,如果要进行jQuery操作,请将其包装为jQuery对象2)直接使用以下方法:$(document).on('click','.event',function(){        //操作});上述方法将具有event类名的元素的点击事件委托给document,当具有event类名的元素触发了点击事件时,则执行对应的事件处理函数

说了这么多,下面通过一个实例来演示如何通过事件委托,实现运行过程中添加元素,仍然具有某些行为的效果:

HTML:

<ul>    <li>        <a class="event" href="##">列表1</a>    </li>    <li>        <a href="##">列表2</a>    </li>    <li>        <a href="##">列表3</a>    </li>    <li>        <a href="##">列表4</a>    </li>    <li>        <a href="##">列表5</a>    </li></ul><button id="add-one">添加一个列表</button>

运行效果:

http://xpzheng.jsp.fjjsp.net//ueditor/jsp/upload/image/20170319/1489904285453075225.png

注意,列表1是有event类名的,当点击具有该类名的超链接时,会将超链接的文本颜色变成红色。点击“添加一个列表”,会在当前列表下追加一个列表项,添加的列表项的超链接带有event类名,我们希望添加一个列表项后,超链接点击后仍然能“变色”。

点击效果:

http://xpzheng.jsp.fjjsp.net//ueditor/jsp/upload/image/20170319/1489904550890012962.png

JS: 点击“添加一个列表”追加列表项:

$('#add-one').on('click',function(){    var $lastLi = $('ul li:last'),        count = $lastLi.index()+ 2,        $li = $('<li><a href="##" class="event">列表'+count+'</a></li>');    $lastLi.after($li);});

点击效果:

http://xpzheng.jsp.fjjsp.net//ueditor/jsp/upload/image/20170319/1489904591250028151.png

JS:事件委托,将.event类名超链接的事件委托给document:

$(document).on('click','a.event',function(){   $(this).css('color','#FF0000');});

点击新添加的列表项的超链接后的效果:

http://xpzheng.jsp.fjjsp.net//ueditor/jsp/upload/image/20170319/1489904693968075593.png

很显然,我们没有重新为新添加的元素绑定单击事件,但是事件还是执行了,这就是“事件委托”的魅力所在了!

“事件委托”对于项目开发具有很重要的意义,因为前端操作难以避免新增元素,如果每次重新绑定事件,将使得代码很难维护,有了“事件委托”后就不需要操心了!

感谢阅读!

1 0
原创粉丝点击