body click js 委托_javascript事件委托和jquery事件委托

元旦过后,新年第一篇。

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

事件委托的定义:

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

事件委托的优势:

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

对于在页面进行处理过后新增的dom元素,运用事件委托可以为新增的dom元素一并增减事件处理程序;

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

第一个p

第二个p

第三个p

这是子集菜单

我是子集的div

我是子集的p

点击加一

一、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[i].οnclick= function(){

this.style.background = 'red'

}

}

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

568f93410345

图一

那么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() //先执行一遍循环

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

568f93410345

图二

这时候虽然解决了为新增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.οnclick= 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'

}

}

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

568f93410345

图三

二、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标签'+inner+'

'))

})

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

568f93410345

图四

例二:

第一个p

第二个p

第三个p

span

这是子集菜单

我是子集的div

我是子集的p

点击加一

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标签'+inner+'

'))

})

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

568f93410345

图五

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

js事件委托:不同操作

let events = document.getElementById('events');

let content = document.getElementById('content');

events.οnclick=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)

}

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

568f93410345

图六

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($('

这是增加按钮
'))

}

function deleteEvent(){

$('#content').append($('

这是删除按钮
'))

}

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

568f93410345

图七

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

2019我在路上,加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值