在优化网页性能的技巧当中,对DOM的优化是必不可少的。这其中就涉及到了javascript对DOM的频繁操作。比如响应用户操作的事件。一般情况下,如果是稍微初级一点的前端程序员,在拿到项目的时候,对待添加DOM事件,可能有些不会去考虑到这个性能的优化问题(比如我),这就会导致页面中有大量的冗余的DOM操作事件。无疑是增加了内存和开销同时降低了网页的性能。

在对添加DOM事件,可以尝试着去优化一下代码。这就是这里要说到的事件委托机制。事件委托机制的含义在网上一搜无论是官方的解释还是广大网友的分享。都可以大概从其中理解到一些:对于子元素需要添加的事件,把它委托给父元素。也就是说在父元素上绑定这个事件。当子元素触发事件时,会冒泡到父元素上面,自然就会触发这个绑定在父元素上面的事件了。

对于上述的事件委托,有两个需要理解的问题:事件冒泡,获取触发事件的元素。

1)事件冒泡:

要说到事件冒泡的话,就要说说它的对手,事件捕获。这两者都属于事件流。也就是说事件流是分为冒泡事件流和捕获事件流。事件流的解释就是--页面接收事件的顺序。

冒泡就是自下而上。像冒泡泡一样从子元素一直往上窜。而捕获刚好相反:从页面根节点(document)到里层元素。这两个事件使用频率比较高的是事件冒泡。比如这里要用到的事件委托,就是使用到了事件冒泡机制。

2)获取触发事件的元素

当父元素里面的子元素触发了事件,这个时候,就会发生事件的冒泡,一直到绑定事件的父元素上面就会触发事件。事件冒泡的图截取网上的如下:

冒泡到父元素之后,父元素如何得知此时是哪个子元素触发了事件呢?这会使用到一个event对象。event的获取和它的一些比较详细的介绍可自行网上搜索。而这里需要使用到的是event的一些属性

(1)   event.target /event.srcElement

获取事件源(源头),也就是事件到底是由谁触发的,而不是说事件绑定在谁身上谁才能触发。比如这里说的事件绑定在父元素上,但是子元素可以触发这个事件。

(2)event.target.nodeName

target下面的nodeName或者什么id,className之类的都是要获取具体的子元素。因为target它得到的是形如这样的:

<li class="myLi">第一项</li>

有了上面这些之后,就可以着手去写事件代理了:

给父元素ul绑定事件

如上所示,当点击某一个li的时候,li的background变为lightgray,其他的保持white颜色。这就是事件的代理。只给父元素添加事件。而子元素通过冒泡的形式冒到父元素的时候就会触发这个绑定的事件。这就明显的减少了对DOM 的操作。从而优化了网页的性能。

上面有一个注释掉的一段代码。它的这个意思是:事件绑定到父元素的上面,那么子元素点击一定会触发父元素的事件。但是这个时候我不想要子元素触发父元素的事件。此时抛掉这个事件代理。因为这个跟事件代理没什么关系了。所以我要阻止子元素触发父元素事件的话。有个方法是在每个子元素上添加事件,并且阻止冒泡的传递。这样感觉又得不偿失了。所以使用e.target判断当前点击的是子元素的话就不要触发这个事件。也就只有点击的是自己的时候才触发这个事件。

回到事件代理。如果子元素的事件都不一样,那么代码就需要进行相应的修改了。可以使用到这个e.target上的一系列比如id,className之类的来判断当前点击的是哪个子元素,然后使用if/else,或者switch也好。分别进行处理。

当然事件冒泡也不是所有的事件都带有的。有的事件就没有。当然我们常用的click,键盘事件,mousedown这样的。是可以冒泡的。但是focus/blur这些就不可以冒泡。关于哪些事件不能冒泡需要网上查阅一下资料。在使用的时候注意一下就可以了。

js 事件委托代理的更多相关文章

  1. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  2. 什么是JS事件冒泡?

    什么是JS事件冒泡?: 在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理 程序或者事件返回true,那么 ...

  3. js事件技巧方法整合

    window.resizeTo(800,600); //js设置浏览器窗口尺寸 window.open (function(){ resizeTo(640,480);//设置浏览器窗口尺寸 moveT ...

  4. js事件浅析

    js中关于DOM的操作很多,因此js事件机制也就尤为重要. 事件绑定形式: 一. 内联形式 耦合度高,不利于维护 <button onclick="alert('你点击了这个按钮'); ...

  5. js 事件大全

    Js事件大全一般事件 事件 浏览器支持 描述onClick IE3|N2|O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击onDblClick IE4|N4|O 鼠标双击事件onMouseDo ...

  6. 原生JS事件绑定方法以及jQuery绑定事件方法bind、live、on、delegate的区别

    一.原生JS事件绑定方法: 1.通过HTML属性进行事件处理函数的绑定如: <a href="#" onclick="f()"> 2.通过JavaS ...

  7. JS事件

    JS事件:  声明:为了事件对象event跨浏览器兼容: var oEvent==ev||event;      所以在下面用到 event 的地方都用 oEvent 代替  1)doucument的 ...

  8. 原生js事件和jquery事件的执行顺序问题

    场景:近日,写前端页面时候,在针对输入框input操作时,用到了jquery的插件,插件中使用了jquery的focus()和blur()方法.但是同时,又需要在插件之外再针对输入框的获取焦点和失去焦 ...

  9. 特殊js事件

    1:点击enter事件 $(document).keypress(function(e) { // 回车键事件 if(e.which == 13) { submitForm(); } }); 2:JQ ...

随机推荐

  1. Hive在drop表的时候报错

    问题背景: 在安装完Hive之后,初始化mysql是成功的,hive启动也是成功的,也能创建database,在database中也能创建表,也能查看表结构,但是在drop的时候就不行了,在hive ...

  2. Oracle修改日志归档模式、归档路径以及空间大小的相关测试

    ORACLE 创建数据库的时候要不要开启日志归档? oracle数据库可以运行在2种模式下:归档模式(archivelog)和非归档模式(noarchivelog) .归档模式可以提高Oracle数据 ...

  3. Oracle的卸载过程步骤

    用Oracle自带的卸载程序不能从根本上卸载Oracle,从而为下次的安装留下隐患,那么怎么才能完全卸载Oracle呢?那就是直接注册表清除,步骤如下: 1. 开始->设置->控制面板-& ...

  4. (转)Python中的上下文管理器和Tornado对其的巧妙应用

    原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...

  5. python 继承 多态

    python 的继承 #-*- coding:utf-8 -*-class A(object): def __init__(self): print('A:我是肯定会执行的!!') def fun(s ...

  6. 工厂模式——java设计模式

    工厂模式 目录 何为工厂模式 工厂方法与抽象工厂 如何在Java EE中通过@Producers与@Inject注解实现工厂模式 如何创建自定义注解以及通过@Qualifier消除具体实现之间的歧义 ...

  7. CentOS Java C JNI

    使用JNI调用本地代码,整个开发流程主要包括以下几个步骤: 1.创建一个Java类(IntArray.java): 2.使用javac编译该类(生成IntArray.class): 3.使用javah ...

  8. Docker基础教程(命令详解)

    # docker --help Usage: docker [OPTIONS] COMMAND [arg...] docker daemon [ --help | ... ] docker [ -h ...

  9. android开发学习笔记系列(3)--ScrollView与HorizontalScrollView

    ScrollView与HorizontalScrollView 这是一个滚动视图,就是说如果你在你的UI中容不下那么多的内容,且你对自己的UI都已经设置好了px,OK,那么在适应屏幕过程中,我们并不希 ...

  10. shell命令——if

    if中[ ]实际上调用的是test的一种快捷方法.bash的数值和字符串比较运算符: 注意=两边的空格 字符串 数值 为真,如果 x = y x -eq y   x != y x -ne y   x ...