JavaScript 事件对内存和性能的影响
作者:前端李李 发布时间:2024-07-31 14:45:36
虽说事件处理程序可以为现代 Web 页面添加很强的交互能力,但是不分青红皂白就添加大量的事件处理程序绝对是一种愚蠢的行为。
我们来分析一下:事件处理程序本质上是一种函数,是一种对象,存放在内存中,设置大量的事件处理程序会使内存中的对象变多,Web 程序的性能会变得越来越差,用户体验很不好。
为了更好地利用好事件处理程序,便出现了事件委托,用来提升性能。
事件委托
事件委托(event delegation):把若干个子节点上的相同事件的处理函数绑定到它的父节点上去,在父节点上统一处理从子节点冒泡上来的事件,这种技术就叫做事件委托。
补充一下:事件委托并不局限于父节点与子节点之间。也可以这样玩,比如页面文档中有好多个处在不同位置地 button,都是绑定 click 事件,使用事件委托,我们可以把这些个事件统一绑定到 body 元素,然后再进行处理(虽然一般很少这么用)。
下面举例子逐步说明事件委托的优势:
<ul id="parent-list">
<li id="list-1">List 1</li>
<li id="list-2">List 2</li>
<li id="list-3">List 3</li>
<li id="list-4">List 4</li>
<li id="list-5">List 5</li>
</ul>
假设有上面的代码,我们现在有一个需求:就是无论单击上面的列表(ul)的哪个子列表(li),都会弹出一个框,来显示我们点击了哪个子列表。
需求不难吧?有了需求,接下来是该写 js 代码了,现在有两种方法放在你眼前:1. 为每个 li 子元素绑定 click 事件,然后设置处理函数; 2. 利用事件委托,为 ul 父元素绑定 click 事件,然后设置处理函数
// 方法一
var list1 = document.getElementById("list-1");
list1.addEventListener("click",function(){
alert(this.firstChild.nodeValue);
},false);
var list2 = document.getElementById("list-2");
list2.addEventListener("click", function() {
alert(this.firstChild.nodeValue);
}, false);
var list3 = document.getElementById("list-3");
list3.addEventListener("click", function() {
alert(this.firstChild.nodeValue);
}, false);
var list4 = document.getElementById("list-4");
list4.addEventListener("click", function() {
alert(this.firstChild.nodeValue);
}, false);
var list5 = document.getElementById("list-5");
list5.addEventListener("click", function() {
alert(this.firstChild.nodeValue);
}, false);
// 方法二
var parentList = document.getElementById("parent-list");
parentList.addEventListener("click",function(){
var target = event.target;
if(target.nodeName.toLowerCase() === "li"){
alert(target.firstChild.nodeValue);
}
},false);
看着上面的代码,我这里写几点方法二的优点:1. 减少了访问 DOM 的次数,提升了性能;2. 将子元素的事件处理程序统一绑定到其父元素,减少了对内存的占用;3. 可以更好地管理事件处理程序,比如移除对某个事件处理程序的引用
注意:如果对各个子元素的需求不一样,我们还可以这样来改写上面的方法二:
// 方法二
var parentList = document.getElementById("parent-list");
parentList.addEventListener("click",function(){
var target = event.target;
if(target.nodeName.toLowerCase() === "li"){
switch(target.id){
case "list-1":
alert("学的越多,越觉得自己无知!");
break;
case "list-2":
alert("爱是一种艺术!");
break;
case "list-3":
target.innerHTML = "呵呵,我改了啊!";
break;
case "list-4":
target.style.background = "#aaa";
break;
case "list-5":
target.style.color = "red";
target.style.fontSize = "2em";
break;
default:
break;
}
}
},false);
因为事件委托依赖事件冒泡机制,所以,并不是所有的事件都可以进行事件委托。
最适合采用事件委托的事件包括:click、mousedown、mouseup、keydown、keyup 和 keypress。
事件委托只是一种非常不错的事件绑定的思想,所以不应该拘泥于上面的例子,要活学活用! ^_^
移除事件处理程序
我们前面说过,事件处理程序存在于内存中,每当将事件处理程序指定给元素时,运行中的浏览器代码与支持页面交互的 JavaScript 代码之间就会建立一个连接。这种连接越多,页面执行就越慢。前面所说的事件委托就是用来限制建立的连接数量。
还有,就是内存中那些使用完后不再使用的事件处理程序,如果不释放掉,也会影响 Web 应用程序的内存和性能。
<button id="button">提交</button>
var button = document.getElementById("button");
button.onclick = function(){
// 提交某个表单的操作代码
button.onclick = null; // 移除事件处理程序
event.target.firstChild.nodeValue = "提交中。。。";
};
总的原则就是:移除掉那些过时不再使用的事件处理程序,释放内存!
来源:http://www.qdfuns.com/notes/36458/e27e3337730e48f7a5b0400db860ea18.html


猜你喜欢
- 用mysqlbinlog.exe查看二进制日志是否启用了日志mysql>show variables like 'log%
- 一、为何人工智能(AI)首选Python?读完这篇文章你就知道了。我们看谷歌的TensorFlow基本上所有的代码都是C++和Python,
- 前言判断文件是否存在在实际应用中用的非常多,下面我们来归纳一下检查文件、文件夹是否存在的各种操作一.检查文件夹/文件是否存在1. os.pa
- 图片太大了,上百张图用photoshop改太慢,就想到用python写个简单的批处理。功能简单就是把原图按比例缩小# -*- coding:
- vue循环动态设置ref并获取$refs关于ref的使用和场景请看官网文档下面是我对循环设置ref并获取使用的一些办法,简单记录一下一. 使
- 代码很简洁,功能很实用,这里就不多废话了,直接奉上:<?php/** * 获取客户端IP * @param&nbs
- 本文实例讲述了python实现备份目录的方法。分享给大家供大家参考。具体如下:备份脚本1:#!/usr/bin/python# Filena
- 前言:最近在做SOSO地图相关开发,遇到相关画圆知识,特此简单记录下来。1.在页面中添加SOSO地图API引用,引用脚本:<scrip
- 概述WSGI接口包含两方面:server/gateway 及 application/framework。server调用由applicat
- 在进行浮动布局时,大多数人都深知,在必要的地方进行浮动清理:<div style="clear:both;">
- 在Windows平台上,从原来使用C/C++编写原生EXE程序,到使用Python编写一些常用脚本程序,成熟的模块的使用使得编程效率大大提高
- 前言:本文的主要内容是介绍Python中的变量命名规则和简单数据类型的应用,简单的数据类型包括字符串和数字等,文中还附有代码以及相应的运行结
- 前言滑块拼图验证码的失败难度在于每次图片上缺口位置不一样,需识别图片上拼图的缺口位置,使用python的OpenCV库来识别到环境准备pip
- 需要用到2个库,requestsocks5-http-client/lib/Agent/或socks5-https-client/lib/A
- HP注释规范注释在写代码的过程中非常重要,好的注释能让你的代码读起来更轻松,在写代码的时候一定要注意注释的规范。“php是一门及其容易入门的
- 使用JS对Json数据的处理,项目遇到需要对Json数据进行相关操作,比如增删改操作,本以为会比较难,网上搜索下,发现还是比较简单的,贴一段
- 一、框架架构二、项目目录结构三、框架功能说明解决痛点:通过session会话方式,解决了登录之后cookie关联处理框架天然支持接口动态传参
- concat()是将tensor沿着指定维度连接起来。其中tensorflow1.3版中是这样定义的:concat(values,axis,
- 今天的文章来自 盏茶作酒 同学。他在老电脑中发现了一个加密的 zip 文件,于是用 Python 破解了文件密码。在破解的过程中出现了内存爆
- 最近心血来潮加上有点闲情,动手写了第一个JavaScript版的俄罗斯方块Easy Tetris.先上Easy Tetris俄罗斯方块游戏截