元旦过后,新年第一篇。

初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解读事件委托的地方来认识了解他的原理,本篇文章汇总了两个版本的事件委托:javascript、jquery;

事件委托的定义:

利用事件冒泡,指定一个事件处理程序,就可以管理某一类型的所有事件。

事件委托的优势:

  • 在js中添加到页面上的事件处理程序的个数直接影响到网页的运行性能。因为每个事件处理函数都是一个对象,是对象就会占用内存,而内存中对象越多,导致的结果就是性能越差;而访问dom的次数越多,就会引起结构的重绘或者重排的次数也随之增多,会延迟整个页面的交互就绪时间;
  • 对于在页面进行处理过后新增的dom元素,运用事件委托可以为新增的dom元素一并增减事件处理程序;

在下面的代码中p标签要实现的效果是鼠标点击p标签的时候背景色变为红色,以下是js、jq的处理方法

<body>
<div id="nodes">
<P class="node_p">第一个p</P>
<P class="node_p">第二个p</P>
<P class="node_p">第三个p</P>
<div id="childDiv">
<p>这是子集菜单</p>
<div>我是子集的div
<p>我是子集的p</p>
</div>
</div>
</div>
<button>点击加一</button>
</body>

一、js事件委托

在js中不用事件委托的情况:获取页面中所有的p标签然后用for循环遍历给每一个元素增加事件处理函数

let nodes = document.getElementById("nodes");
let ps = document.getElementsByTagName("p");
console.log(ps);
let btn = document.getElementsByTagName("button")[0];
let inner = 33; btn.onclick = function() {
inner++;
let p = document.createElement("p");
p.innerHTML = inner + "新增的p标签啊";
nodes.appendChild(p);
console.log(ps);
};
for (let i= 0;i<ps.length;i++){
ps[i].onclick= function(){
this.style.background = 'red'
}
}

这时候在浏览器中运行之后进行测试,发现如图一所示的结果;



那么js不用事件委托怎么给新增加的标签添加事件处理函数呢?解决方案如下:

let nodes = document.getElementById("nodes");
let ps = document.getElementsByTagName("p");
console.log(ps);
let btn = document.getElementsByTagName("button")[0];
let inner = 33; btn.onclick = function () {
inner++;
let p = document.createElement("p");
p.innerHTML = inner + "新增的p标签啊";
nodes.appendChild(p);
addEvent();//将新dom元素增加到页面后再执行循环函数
console.log(ps);
}; function addEvent() {
for (let i = 0; i < ps.length; i++) {
ps[i].onclick = function () {
this.style.background = 'red'
}
}
}
addEvent() //先执行一遍循环

这时候浏览器中运行如图二所示:



这时候虽然解决了为新增dom元素增加事件处理函数的问题,但是仔细考虑他的性能却是比之前都有所下降,究其原因就是又增加了一个事件处理函数(对象),又一次占用了内存;所以,这个时候就会用到事件委托,这时候事件委托的优势也有所体现出来:

let nodes = document.getElementById("nodes");
let ps = document.getElementsByTagName("p");
console.log(ps);
let btn = document.getElementsByTagName("button")[0];
let inner = 33; btn.onclick = function () {
inner++;
let p = document.createElement("p");
p.innerHTML = inner + "新增的p标签啊";
nodes.appendChild(p);
console.log(ps);
};
//事件委托,为nodes指定一个事件处理函数,处理nodes下为p标签的所有元素的cilck事件
nodes.onclick= function(e){
let ev = e || window.event
let target = ev.target || ev.srcElement //srcElement IE浏览器
//这里要判被处理元素节点的名字,也可以增加相应的判断条件 target.nodeName.toLowerCase() == 'p'||target.nodeName.toLowerCase() == 'span',但是要注意不要使用父级元素的名称,因为再点击子元素之间的空气的时候,由于事件冒泡他会给父级元素也增加相应的事件处理函数;因为返回的节点名称一般都是大写,所以这时要用toLowerCase()处理一下;
if(target.nodeName.toLowerCase() == 'p'){
target.style.background = 'green'
}
}

这时候浏览器中运行的结果如图三所示:

二、jquery事件委托:

相较于js事件委托,jquery事件委托的优势:执行事件委托的时候只有子元素会触发事件函数,而代为执行的父元素不会触发事件函数,因此不用去判断元素节点的名称;(注意这里的事件委托用的方法on,如果用bind方法父元素会触发事件函数)

这里nodes节点下所有标签为p的子节点都被赋予事件处理函数;这里的子节点还可以是多个类似' p,span',需要注意这里面也不可以写同nodes一样的标签,否则点击元素之间的间隔会给nodes下的div赋予事件处理函数;如例二:

例一:

let inner = 33;
//这里nodes节点下所有标签为p的子节点都被赋予事件处理函数;这里的子节点还可以是多个类似' p,span',需要注意这里面也不可以写同nodes一样的标签,否则点击元素之间的间隔会给nodes下的div赋予事件处理函数
$('#nodes').on('click','p',function(e){
let target = $(e.target)
target.css('backgroundColor','red')
})
$('button').click(()=>{
inner++;
$('#nodes').append($('<p>我是新增加的p标签'+inner+'</p>'))
})

浏览器运行的效果如图四所示:



例二:

<body>
<div id="nodes">
<P class="node_p">第一个p</P>
<P class="node_p">第二个p</P>
<P class="node_p">第三个p</P>
<span class="node_p">span</span>
<div id="childDiv">
<p>这是子集菜单</p>
<div>我是子集的div
<p>我是子集的p</p>
</div>
</div>
</div>
<button>点击加一</button>
</body>
<script>
let inner =33;
$('#nodes').on('click','p,div,span',function(e){
let target = $(e.target)
target.css('backgroundColor','red')
})
$('button').click(()=>{
inner++;
$('#nodes').append($('<p>我是新增加的p标签'+inner+'</p>'))
})
</script>

浏览器运行效果如图五所示:

事件委托不仅仅只是为处理一种dom操作类型,他可以进行增删改查等功能:

js事件委托:不同操作

<body>
<div id="events">
<input type="button" id='addHandle' value='增加'>
<input type="button" id='deleteHandle' value='减少'>
</div>
<div id="content"> </div>
</body>
<script src='http://code.jquery.com/jquery-2.1.1.min.js'></script>
<script>
let events = document.getElementById('events');
let content = document.getElementById('content');
events.onclick=function(e){
let ev = e || window.event;
let target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase()=='input'){
switch(target.id){
case 'addHandle':
return addEvent();
break
case 'deleteHandle':
return deleteEvent();
break
}
}
}
function addEvent(){
let add = document.createElement('p')
add.innerHTML = '这是增加按钮'
content.appendChild(add)
}
function deleteEvent(){
let del = document.createElement('p')
del.innerHTML = '这是删除按钮'
content.appendChild(del)
}
</script>

浏览器中的效果如图六所示:

jquery事件委托:不同操作

$('#events').on('click','input',(e)=>{
let target = $(e.target);
switch(target[0].id){
case 'addHandle':
return addEvent();
break
case 'deleteHandle':
return deleteEvent();
break
}
})
function addEvent(){
$('#content').append($('<div>这是增加按钮</div>'))
}
function deleteEvent(){
$('#content').append($('<div>这是删除按钮</div>'))
}

浏览器中的效果如图七所示:

本文如有不实之处,还望大神指点一二,欢迎讨论!

2019我在路上,加油!

javascript事件委托和jquery事件委托的更多相关文章

  1. javascript事件委托和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  2. javascript 事件委托 和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  3. javascript事件委托和jQuery事件绑定on、off 和one以及on绑定多个事件(重要)

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  4. js事件委托和jQuery事件绑定on , off , one , bind , unbind , die

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  5. JavaScript 中的window.event代表的是事件的状态,jquery事件对象属性,jquery中如何使用event.target

    http://wenda.haosou.com/q/1373868839069215 http://kylines.iteye.com/blog/1660236 http://www.cnblogs. ...

  6. jQuery基础(4)- 位置信息、事件流、事件对象、事件代理、jquery事件

    一.jQuery的位置信息 jQuery的位置信是JS的client系列.offset系列.scroll系列封装好的一些简便api. 1.宽度和高度 a.获取宽度和高度,例如: .width() // ...

  7. jquery easyui控件事件监听委托给jquery事件监听,keyup取最新值问题

    <div id="<?php echo NS; ?>toolbar"> <div style="padding:5px"> ...

  8. javascript 第28节 jQuery事件、迭代、样式

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. jQuery源代码学习之九—jQuery事件模块

    jQuery事件系统并没有将事件坚挺函数直接绑定在DOM元素上,而是基于事件缓存模块来管理监听函数的. 二.jQuery事件模块的代码结构 //定义了一些正则 // // //jQuery事件对象 j ...

随机推荐

  1. 真正认识 realloc 的工作方式(转载)

    转自:http://www.cnblogs.com/ren54/archive/2008/11/20/1337545.html realloc 用过很多次了.无非就是将已经存在的一块内存扩大. cha ...

  2. bzoj3118: Orz the MST(线性规划+单纯形法)

    传送门 不难发现,对于每一条树边肯定要减小它的权值,对于每一条非树边要增加它的权值 对于每一条非树边\(j\),他肯定与某些树边构成了一个环,那么它的边权必须大于等于这个环上的所有边 设其中一条边为\ ...

  3. 使用Docker Compose编排微服务

    一般微服务架构会包含若干个微服务,而每个微服务可以有多个实例,如果每个微服务都有手动启停,那么效率就很低.维护量比较大. 所以我们可以使用Docker Compose来轻松.高效地管理容器. 一.安装 ...

  4. CAD中的文本编排操作

        AutoCAD中导入超文本实现方法 除了AutoCAD内含的文本输入命令外,向AutoCAD中输入多行文本即超文本的方法还有:通过Windows提供的剪贴板,利用AutoCAD提供的多行文本命 ...

  5. __new__问题

    当类实例化的时候,通过__new__来创建对象空间, 如果实例化的时候带参数,那么__new__也是必须接受这个参数的,不接受会报错,而且这个__new__的返回值, 是传给__init__里面的se ...

  6. Hdu 5379 Mahjong tree (dfs + 组合数)

    题目链接: Hdu 5379 Mahjong tree 题目描述: 给出一个有n个节点的树,以节点1为根节点.问在满足兄弟节点连续 以及 子树包含节点连续 的条件下,有多少种编号方案给树上的n个点编号 ...

  7. C# 判断文件和文件夹是否存在并创建

    C# 判断文件和文件夹是否存在并创建 using System; using System.Data; using System.Configuration; using System.Collect ...

  8. AngularJS ng-repeat下使用ng-model

    1 2 3 blue:<input type="radio" value="1" ng-model="selectValue"/> ...

  9. AJPFX总结正则表达式的概述和简单使用

    正则表达式的概述和简单使用* A:正则表达式        * 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用.        * 作用:比如注 ...

  10. SpringBoot 2.x (4):配置文件与单元测试

    SpringBoot的配置文件有默认的application.properties 还可以使用YAML 区别: application.properties示例: server.port=8090 s ...