说明

上次我们说了一些,关于 JavaScript中事件委托的 基础知识,这次我们继续来看。

解释

先来一段代码

<!doctype html>
<html lang="en">
</head>
<body>
<ul id=ul>
<li id='li1'>1</li>
<li id='li2'>2</li>
</ul> <script>
ul.onclick = function (e){
if(e.target.nodeName == 'LI'){
console.log('li 被点击了');
}
}
</script>
</body>
</html>

上面这段代码,用了事件委托,把事件绑在了ul上,没有给每个 li 都去绑定事件,看上去也是实现效果了,但是如果 li 里面还有子元素,那么这么去绑定事件就不行了,当点击 li 里面的子元素时,就出现问题了。
比如,我们把上面的代码改成这样,看看效果。

<!doctype html>
<html lang="en">
<head>
<style>
li{
padding:20px;
background:red;
}
span{
padding:10px;
background:blue;
}
</style>
</head>
<body>
<ul id=ul>
<!-- 增加子元素 -->
<li id='li1'><span>1</span></li>
<li id='li2'><span>2</span></li>
</ul> <script>
ul.onclick = function (e){
console.log('span 被点击了');
if(e.target.nodeName == 'LI'){
console.log('li 被点击了');
}
}
</script>
</body>
</html>

效果图

看图,当点击 蓝色 span 的时候,没有打印 li 被点击了 ,当点击 红色 li 的时候,才都打印出来,这是因为当点击 span 的时候,事件源是 span,虽然也能触发事件,但是并没有走 if判断,所以就不会打印 li 被点击了 ,当点击 li 的时候,事件源是 li ,所以就可以了,但是我们往往需要的是,不管是点击li,还是点击 了 li 的子元素,都需要执行操作。
好的,我们来改改代码。
这次我们需要 Element.matches( ) 这个方法,

作用:
判断当前DOM节点是否能完全匹配对应的css选择器规则;如果匹配成功,返回true,否则返回false。

语法:

let result = element.matches(selectorString);  

result 的值为 true 或 false
selectorString 是个css选择器字符串

举例:

<div id="d"> 这是一个div元素 </div>

<script type="text/javascript">
var el = document.getElementById("d");
if (el.matches("div")) {
alert("匹配到了!"); //能显示弹框,因为"div"选择器可以选择到el元素
}
</script>

至于更多关于 Element.matches( ) 方法的细节,和对于不支持 Element.matches( ) 方法的浏览器的替代方案,请到这里查看
Element.matches( )

<!doctype html>
<html lang="en">
<head>
<style>
li{
padding:20px;
background:red;
}
span{
padding:10px;
background:blue;
}
</style>
</head>
<body>
<ul id=ul>
<!-- 增加子元素 -->
<li id='li1'><span>1</span></li>
<li id='li2'><span>2</span></li>
</ul> <script>
ul.onclick = function (e){
//获取事件源
var target = e.target; //如果 事件源 不是 li 就进入循环
while(!target.matches('li')){
//如果事件源 是 ul 就把事件源 赋值为null,跳出循环
//如果事件源 不是 ul 就把事件源 赋值为事件源的父元素
if(target === ul){
target = null;
break;
}
target = target.parentNode;
}
// 如果 target为 true
//也就是说 事件源是 li,就执行if语句里的代码
if(target){
console.log('li 被点击了');
}
}
</script>
</body>
</html>

效果图

看图,现在这样,不管是点击 li 还是 li 的子元素,就都可以打印出内容了。

jQuery中的事件委托
jQuery中事件委托主要是靠on( ) 方法,我们先来看看 on( ) 方法的使用说明

on( ) 方法主要有以下两种形式的用法
用法一

jQueryObject.on( events [, selector ] [, data ], handler )

用法二

jQueryObject.on( eventsMap [, selector ] [, data ] )
参数 描述
events String类型,一个或多个用空格分隔的事件类型和可选的命名空间,例如"click"、"focus click"、"keydown.myPlugin"。
eventsMap Object类型,一个Object对象,其每个属性对应事件类型和可选的命名空间(参数events),属性值对应绑定的事件处理函数(参数handler)。
selector 可选/String类型,一个jQuery选择器,用于指定哪些后代元素可以触发绑定的事件。如果该参数为null或被省略,则表示当前元素自身绑定事件(实际触发者也可能是后代元素,只要事件流能到达当前元素即可)。
data 可选/任意类型,触发事件时,需要通过event.data传递给事件处理函数的任意数据。
handler Function类型,指定的事件处理函数。

我们再用jQuery的 on( ) 方法实现下,最开始的例子

<!doctype html>
<html lang="en">
<head>
<style>
li{
padding:20px;
background:red;
}
span{
padding:10px;
background:blue;
}
</style>
</head>
<body>
<ul id=ul>
<!-- 增加子元素 -->
<li id='li1'><span>1</span></li>
<li id='li2'><span>2</span></li>
</ul> <script src="http://code.jquery.com/jquery-2.2.4.js"></script>
<script>
$('#ul').on('click','li',function (){
console.log('li 被点击了');
});
</script>
</body>
</html>

更加详细的关于 JQuery中on( )方法的解释,推荐看这里
jQuery.on() 函数详解

总结

用到 事件委托 的地方,应该还是比较多的,希望大家都能理解这个东西。

简单说 JavaScript中的事件委托(下)的更多相关文章

  1. js实例分析JavaScript中的事件委托和事件绑定

    我们在学习JavaScript中,难免都会去网上查一些资料.也许偶尔就会遇到“事件委托”(也有的称我“事件代理”,这里不评论谁是谁非.以下全部称为“事件委托”),尤其是在查JavaScript的事件处 ...

  2. JavaScript中的事件委托机制跟深浅拷贝

    今天聊下JavaScript中的事件委托跟深浅拷贝 事件委托 首先呢,介绍一下事件绑定 //方法一:通过onclick <button onclick="clickEvent()&qu ...

  3. JavaScript中的事件委托(转至大佬)

    转至:https://www.cnblogs.com/liugang-vip/p/5616484.html 起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没 ...

  4. javascript中的事件委托

    这几天看到一个面试题,大概就是,让你给1000个li都添加一个click事件,应该怎么添加?大多数人第一开始的感觉可能就是,每个li上边都添加一个呗,那要是这样的话,估计面试的时候就会GG了,这里就是 ...

  5. 理解Javascript中的事件绑定与事件委托

    最近在深入实践js中,遇到了一些问题,比如我需要为动态创建的DOM元素绑定事件,那么普通的事件绑定就不行了,于是通过上网查资料了解到事件委托,因此想总结一下js中的事件绑定与事件委托. 事件绑定   ...

  6. 怎么理解js中的事件委托

    怎么理解js中的事件委托 时间 2015-01-15 00:59:59  SegmentFault 原文  http://segmentfault.com/blog/sunchengli/119000 ...

  7. 了解javascript中的事件(二)

    本文目录如下: 零.寒暄 一.事件的分类 二.事件代理 2.1 问题引出 2.2 什么是事件代理 2.3 完整示例 二.事件代理 三.事件代理思想的用处 四.总结 零.寒暄 这篇博客本该出现在两个月以 ...

  8. 深入理解javascript中的事件循环event-loop

    前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...

  9. JavaScript中的事件循环机制跟函数柯里化

    一.事件循环机制的理解 test();//按秒输出5个5 function test() { for (var i = 0; i < 5; i++) { setTimeout(() => ...

随机推荐

  1. Part-Selenium-1

    1.在浏览器中的console输入:帮助定位 > $x('xpath表达式') > $('css表达式') 2.driver > chrome driver: https://npm ...

  2. RDD(八)——缓存与检查点

    RDD通过persist方法或cache方法可以将前面的计算结果缓存,默认情况下 persist() 会把数据以序列化的形式缓存在 JVM 的堆空间中. 但是并不是这两个方法被调用时立即缓存,而是触发 ...

  3. rest framework-视图和路由-长期维护

    ###############   三种视图    ############### # 第一种方法:使用mixins # class AuthorView(mixins.ListModelMixin, ...

  4. iOS动画效果合集、飞吧企鹅游戏、换肤方案、画板、文字效果等源码

    iOS精选源码 动画知识运用及常见动画效果收集 3D卡片拖拽卡片叠加卡片 iFIERO - FLYING PENGUIN 飞吧企鹅SpriteKit游戏(源码) Swift封装的空数据提醒界面Empt ...

  5. pycharm里配置了项目虚拟环境,terminal打开并不是在虚拟环境下,如何解决

    在pycharm里,点开下方的Terminal,此时默认目录为当前项目对应的根目录, 第一步:输入  cd   venv\Scripts  进入Scripts目录 第二步:然后运行activate.b ...

  6. JVM 的内存布局

    这是jdk7以后的版本 1. Heap(堆区) Heap OOM 障最主要的发源地, 它存储着几乎所有的实例对象, 堆由垃圾收集器自动回收, 堆区由各子线程共享使用.通常情况下 它占用的空间是所有内存 ...

  7. linux openjdk安装

    sudo apt-get install openjdk-8-jdk 默认提示是 sudo apt-get install openjdk-8-jre, 这个只有jre https://openjdk ...

  8. JavaScript学习总结(五)原型和原型链详解

    转自:http://segmentfault.com/a/1190000000662547 私有变量和函数 在函数内部定义的变量和函数,如果不对外提供接口,外部是无法访问到的,也就是该函数的私有的变量 ...

  9. h指数|JCR|ORCID|CCC|Research ID|BKCI|

    h指数有如下缺点: 年龄大且平庸的学者比杰出的青年学者的h-index大.学科之间h指数的评价标准不同.有时候,审稿人暗示作者引用自己文章. 再此处可找到相关信息: JCR上可以查询到影响因子,以下是 ...

  10. zabbix的MariaDB数据库改变存储位置

    #创建 mkdir /公司缩写/mysql   #停止数据库服务 systemctl status mariadb.service systemctl stop mariadb.service   # ...