文档章节

JavaScript事件代理和委托详解(冒泡)

大头儿子程序猿
 大头儿子程序猿
发布于 2017/04/27 16:22
字数 973
阅读 5
收藏 0
点赞 0
评论 0

JavaScript事件代理
事件代理在JS世界中一个非常有用也很有趣的功能。当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。

这主要得益于浏览器的事件冒泡机制,下面我们具体举个例子来解释如何使用这个特性。

这个例子主要取自David Walsh的相关文章(How JavaScript Event Delegation Works)。

假设有一个 UL 的父节点,包含了很多个 Li 的子节点:

?

1

2

3

4

5

6

7

<ul id="list">

 <li id="li-1">Li 1</li>

 <li id="li-2">Li 2</li>

 <li id="li-3">Li 3</li>

 <li id="li-4">Li 4</li>

 <li id="li-5">Li 5</li>

</ul>

当我们的鼠标移到Li上的时候,需要获取此Li的相关信息并飘出悬浮窗以显示详细信息,或者当某个Li被点击的时候需要触发相应的处理事件。

我们通常的写法,是为每个Li都添加一些类似onMouseOver或者onClick之类的事件监听。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function addListenersLi(liElement) {

  liElement.onclick = function clickHandler() {

   //TODO

  };

  liElement.onmouseover = function mouseOverHandler() {

   //TODO

  }

 }

 

 window.onload = function() {

  var ulElement = document.getElementById("list");

  var liElements = ulElement.getElementByTagName("Li");

   for (var i = liElements.length - 1; i >= 0; i--) {

    addListenersLi(liElements[i]);

   }

 }

如果这个UL中的Li子元素会频繁地添加或者删除,我们就需要在每次添加Li的时候都调用这个addListenersLi方法来为每个Li节点添加事件处理函数。

这会造成添加或者删除过程的复杂度和出错的可能性。

解决问题方法是使用事件代理机制,当事件被抛到更上层的父节点的时候,我们通过检查事件的目标对象(target)来判断并获取事件源Li。

下面的代码可以完成想要的效果: 

?

1

2

3

4

5

6

7

8

9

/ 获取父节点,并为它添加一个click事件

document.getElementById("list").addEventListener("click",function(e) {

 // 检查事件源e.targe是否为Li

 if(e.target && e.target.nodeName.toUpperCase == "LI") {

 //

 //TODO

 console.log("List item ",e.target.id," was clicked!");

 }

});

 

在原生js中 event需要做兼容性处理

var e=window.event || e;

var target=e.target || e.srcElement;

为父节点添加一个click事件,当子节点被点击的时候,click事件会从子节点开始向上冒泡。父节点捕获到事件之后,通过判断e.target.nodeName来判断是否为我们需要处理的节点。并且通过e.target拿到了被点击的Li节点。从而可以获取到相应的信息,并作处理。

事件冒泡及捕获
浏览器的事件冒泡机制,对于事件的捕获和处理,不同的浏览器厂商有不同的处理机制,这里介绍W3C对DOM2.0定义的标准事件。

DOM2.0模型将事件处理流程分为三个阶段:

一、事件捕获阶段,

二、事件目标阶段,

三、事件起泡阶段。

如下图:

事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。

本文转载自:http://www.jb51.net/article/82099.htm

共有 人打赏支持
大头儿子程序猿
粉丝 0
博文 20
码字总数 3454
作品 0
奉贤
程序员
js中的事件委托或是事件代理详解

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

菜鸟的进阶
2017/10/22
0
0
javaScript事件(一)事件流

javaScript事件(一)事件流 一、事件 事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字。 事件是javaScript和DOM之间的桥梁。 你若触发,我便执行——事件发生...

蜗牛奔跑
2015/06/24
0
0
《高性能javascript》 领悟随笔之-------DOM编程篇(二)

《高性能javascript》 领悟随笔之-------DOM编程篇二   序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整个页面文档。DOM编程性能一直以来都...

grootzhang
2016/05/10
0
0
JS和JQ的event对象对比和应用

currentTarget 事件冒泡阶段所在的DOM target, originalTarget原始的DOM 代码测试: 结果分析: 总结: js的event参数中,不管是, , 都是指向第一个触发事件的元素(还没冒泡),而在click事...

前端届的科比
2014/08/11
0
0
jQuery中bind方法与live方法区别

今天做项目时遇到的关于live与bind的问题,经查阅资料所得,live实际上为bind方法的变型,bind方法仅支持当前存在元素的事件绑定,而对于日后js动态生成的元素绑定无效。而live方法则弥补了此...

boxiZen
2013/12/20
0
3
JS和JQ的event对象对比和应用

摘要 js和jq的event对象大同小异,本文简单对比下它们的'click'事件下的不同和应用 js jquery jq event 代码测试: ? 结果分析: ? 总结: js的event参数中,不管是, , 都是指向第一个触发事...

波利beryl
2014/11/17
0
0
绑定live bind click

Jquery中绑定事件有三种方法:以click事件为例 (1)target.click(function(){}); (2)target.bind("click",function(){}); (3)target.live("click",function(){}); 第一种方法很好理解,...

波利beryl
2014/11/17
0
0
Jquery绑定事件(bind和live的区别)

Jquery中绑定事件有三种方法:以click事件为例 (1)target.click(function(){}); (2)target.bind("click",function(){}); (3)target.live("click",function(){}); 第一种方法很好理解,...

FuniK
2013/09/23
0
1
腾讯web前端开发工程师笔试题及答案

腾讯web前端开发工程师笔试题及答案 1、 如何实现事件委托? 首先要知道什么是事件委托。 考虑一个列表,在li的数量非常少的时候,为每一个li添加事件侦听当然不会存在太多性能方面的问题,但...

至简6
2014/07/29
0
0
javascript中容易忽略的基础(一)

title 引言: 本篇文章主要总结了一些javascript中特别基础的内容,主要涉及到,, , 每次被问到,总是能想起一点,但是也总记不全,所以遇到这种情况的时候,就简单的记录一下. DOM0级事件和DOM2级事...

funnycoderstar
2017/11/29
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

pbgo: 基于Protobuf的迷你RPC/REST框架

https://www.oschina.net/p/pbgo

chai2010
35分钟前
0
0
rsync工具介绍、常用选项以及通过ssh同步

linux下的文件同步工具 rsync rsync是非常实用的一个同步工具,可以从a机器到b机器传输一个文件,也可以备份数据,系统默认没有这个工具,要使用命令 yum install -y rsync 安装。 rsync的命...

黄昏残影
50分钟前
0
0
OSChina 周四乱弹 —— 表妹要嫁人 舅妈叮嘱……

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @哈哈哈哈哈嗝:一定要听——The Pancakes的单曲《咁咁咁》 《咁咁咁》- The Pancakes 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :...

小小编辑
今天
245
4
流利阅读笔记30-20180719待学习

重磅:让人类得老年痴呆的竟是它? Lala 2018-07-19 1.今日导读 去年奥斯卡最佳动画长片《寻梦环游记》里有一句经典台词:“比死亡更可怕的,是遗忘”。在电影中,年迈的曾祖母会重复说一样的...

aibinxiao
今天
3
0
1.16 Linux机器相互登录

Linux机器之间以密码方式互相登录 运行命令#ssh [ip address],标准命令:#ssh [username]@ip, 如果没有写用户名,则默认为系统当前登录的用户 命令#w查看系统负载,可查看到连接到该主机的...

小丑鱼00
今天
0
0
about git flow

  昨天元芳做了git分支管理规范的分享,为了拓展大家关于git分支的认知,这里我特意再分享这两个关于git flow的链接,大家可以看一下。 Git 工作流程 Git分支管理策略   git flow本质上是...

qwfys
今天
2
0
Linux系统日志文件

/var/log/messages linux系统总日志 /etc/logrotate.conf 日志切割配置文件 参考https://my.oschina.net/u/2000675/blog/908189 dmesg命令 dmesg’命令显示linux内核的环形缓冲区信息,我们可...

chencheng-linux
今天
1
0
MacOS下给树莓派安装Raspbian系统

下载镜像 前往 树莓派官网 下载镜像。 点击 最新版Raspbian 下载最新版镜像。 下载后请,通过 访达 双击解压,或通过 unzip 命令解压。 检查下载的文件 ls -lh -rw-r--r-- 1 dingdayu s...

dingdayu
今天
1
0
spring boot使用通用mapper(tk.mapper) ,id自增和回显等问题

最近项目使用到tk.mapper设置id自增,数据库是mysql。在使用通用mapper主键生成过程中有一些问题,在总结一下。 1、UUID生成方式-字符串主键 在主键上增加注解 @Id @GeneratedValue...

北岩
今天
2
0
告警系统邮件引擎、运行告警系统

告警系统邮件引擎 cd mail vim mail.py #!/usr/bin/env python#-*- coding: UTF-8 -*-import os,sysreload(sys)sys.setdefaultencoding('utf8')import getoptimport smtplibfr......

Zhouliang6
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部