在 JavaScript 程序的开发中,经常会用到一些频繁触发的 DOM 事件,如 mousemove、resize,还有不是那么常用的鼠标滚轮事件:mousewheel (在 Firefox 中,滚轮事件为 DOMMouseScroll)。

浏览器为了确保这些事件能够及时响应,触发的频率会比较高,具体的触发频率各浏览器虽然有出入,但出入不大。很多时候在需要注重性能的场景下使用这些事件会想各种办法对事件的触发频率进行优化,下面说说我的一些优化方法。

mousemove 在拖拽中的优化

拖拽( Drag )是很常见的一个功能,在浏览器还没实现原生的拖拽之前,通过 mousedown、mousemove、mouseup 3种事件类型就可以模拟出拖拽效果来,当然这里不谈如何去实现一个拖拽功能。

mousemove 事件在拖拽的应用中既要确保拖拽的流畅度,又要确保拖拽时的性能,如何保持两者的平衡呢?

可以通过设置一个计数器来去掉一半的 mousemove 事件的触发,代码如下:

01 var count = 0;
02  
03 elem.onmousemove = function(){
04     count++;
05      
06     // 当计数器为偶数的时候不执行mousemove
07     if( count % 2 === 0 ){
08         return;
09     }
10      
11     // 实现拖拽功能的代码...
12 };

上面只是增加了很少的几行代码,通过判断计数器是否为偶数,就可以去掉一半的 mousemove 事件执行的次数,同时拖拽功能的流畅度基本不受影响。

mousemove 模拟 mouseenter 效果

最近碰到这么一个需求,需要在图片上绑定一个事件,当鼠标移动到图片上时对图片进行放大,绝大多数人的第一反应就是直接使用 mouseenter 事件来处理。但是使用 mouseenter 事件会带来误触发,尽管可以使用定时器来配合也还是会有误触发,因为图片对于 mouseenter 的触发区域是比较大的,当鼠标划过一张 200*200 尺寸的图片时,此时给 mouseenter 设置一个 500 毫秒的延时,效果可能达不到预期。对交互方式做进一步的优化,当鼠标快速划过图片时不触发事件,只有鼠标短暂的停留在图片上时才触发事件。通过对 mousemove 添加一个定时器就可以实现该效果。代码如下:

01 var timer,
02     move = function(){
03         clearTimeout( timer );
04         // 设置一个较短的定时器
05         timer = setTimeout(function(){
06             // 这里是实现图片放大的代码...
07         }, 200 );
08     };
09      
10 img.onmousemove = move;
11 img.onmouseout = function(){
12     clearTimeout( timer );
13 };

鼠标频繁的移动触发的 mousemove 事件会清除掉上一次添加的定时器,只有当鼠标停留时间超过设置的 200 毫秒才会触发事件,当然在鼠标移开的时候一定要记得清除掉定时器。360图片搜索就采用了这种触发方式,这样就不会再有误触发了。

resize 事件的优化

resize 是在浏览器窗口大小改变的时候触发的事件,通常改变一次会触发 2、3 次 resize 事件,对于 IE6/7 resize 更容易被触发。resize 事件通常用于当窗口改变大小时,网页的布局也会根据窗口大小进行自适应布局。自适应布局如果对性能的消耗比较大,那么就要尤为注意 resize 触发的频率。同样使用定时器来实现。

01 var throttle = function( fn, timeout ){       
02     var timer;
03      
04     return function(){
05         var self = this,
06             args = arguments;
07  
08         clearTimeout( timer );
09  
10         timer = setTimeout(function(){
11             fn.apply( self, args );
12         }, timeout );
13     };
14 };
15  
16 window.onresize = throttle(function(){
17     // 自适应布局的代码...
18 }, 100 );

通过反复的调试,发觉给 resize 添加一个 100 毫秒的延迟的效果会比较理想,既能保证事件的及时性,又能达到优化的目的。

mousewheel 事件的优化

mousewheel 是鼠标滚轮滚动时触发的事件,在 Firefox 中该事件名为 DOMMouseScroll,在一些场合下,比如通过鼠标滚轮来控制 lightbox 组件图片的前后切换,又或者通过鼠标滚轮来放大和缩小地图。鼠标滚轮通常都会比较灵活,可能一次会滚动好几次,但是在具体的应用中这种太灵活的滚动在前面提到过的场景中必然会有误触发。直接将上面封装好的 throttle 函数拿过来稍微改下时间间隔同样能达到优化效果。

1 window.onmousewheel = throttle(function(){
2     // 滚轮滚动时的操作代码...
3 }, 200 );

鼠标滚轮设置 200 毫秒的延迟会有较理想的效果。

以上的一些优化方法大多是通过定时器来实现的,关键还是看如何灵活运用了。这些优化并不限于性能上的优化,还有交互效果上的优化,说到底就是以前端的角度出发,从细节入手来提升用户体验。

本文转自:http://stylechen.com/dom-event-optimize.html

浅谈DOM事件的优化的更多相关文章

  1. 前端性能优化--为什么DOM操作慢? 浅谈DOM的操作以及性能优化问题-重绘重排 为什么要减少DOM操作 为什么要减少操作DOM

    前端性能优化--为什么DOM操作慢?   作为一个前端,不能不考虑性能问题.对于大多数前端来说,性能优化的方法可能包括以下这些: 减少HTTP请求(合并css.js,雪碧图/base64图片) 压缩( ...

  2. 转:浅谈CSS在前端优化中一些值得注意的关键点

    前端优化工作中要考虑的元素多种多样,而合理地使用CSS脚本可以在很大程度上优化页面的加载性能,以下我们就来浅谈CSS在前端优化中一些值得注意的关键点: 当谈到Web的“高性能”时,很多人想到的是页面加 ...

  3. 浅谈DOM性能考虑

    浅谈DOM性能考虑 很多人都会忽视脚本对Web应用整体性能的影响.为保证应用的流畅运行,在为文档编写和应用脚本时,需要注意一些问题.一.尽量减少访问DOM和尽量减少标记    访问DOM的方式对脚本性 ...

  4. Js之浅谈dom操作

    JavaScript之浅谈dom操作 1.理解dom: DOM(Document Object Model ,文档对象模型)一种独立于语言,用于操作xml,html文档的应用编程接口. 怎么说,我从两 ...

  5. 浅谈tomcat中间件的优化【转】

    今天来总结一下tomcat的一些优化的方案,由于本人才疏学浅,写的不好,勿喷! tomcat对于大多数从事开发工作的童鞋应该不会很陌生,通常做为默认的开发环境来为大家服务,不过tomcat默认的一些配 ...

  6. [原创]浅谈H5页面性能优化方法

    [原创]浅谈H5页面性能优化方法 前阶段公司H5页面性能测试,其中测试时也发现了一些性能瓶颈问题,接下来我们在来谈谈H5页面性能优化,仅仅是一些常用H5页面性能优化措施,其实和Web页面性能优化思路大 ...

  7. MYSQL优化浅谈,工具及优化点介绍,mysqldumpslow,pt-query-digest,explain等

    MYSQL优化浅谈 msyql是开发常用的关系型数据库,快速.稳定.开源等优点就不说了. 个人认为,项目上线,标志着一个项目真正的开始.从运维,到反馈,到再分析,再版本迭代,再优化… 这是一个漫长且考 ...

  8. 浅谈Unity的渲染优化(1): 性能分析和瓶颈判断(上篇)

    http://www.taidous.com/article-667-1.html 前言 首先,这个系列文章做个大致的介绍,题目"浅谈Unity",因为公司和国内大部分3D手游开发 ...

  9. 浅谈Javascript事件模拟

    事件是用来描述网页中某一特定有趣时刻的,众所周知事件通常是在由用户和浏览器进行交互时触发,其实不然,通过Javascript可以在任何时间触发特定的事件,并且这些事件与浏览器创建的事件是相同的.这就意 ...

随机推荐

  1. Java 开发者的编程噩梦,为什么你的代码总有 bug🐛?

    文章已经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所需要掌握的核心知识,欢迎Star和指教. 欢迎关注我的公众号,文章每周更新. 很多 Java 初学者在 ...

  2. three.js 制作机房(下)

    这一篇书接上文,说一说剩下的一些模块. 1. 机箱存储占用比率 机箱存储占用比其实很简单,就是在机箱上新加一个组即可,然后根据比率值来设置颜色,这个颜色我们去HSL(0.4,0.8,0.5) ~ HS ...

  3. python设计模式之适配器模式

    python设计模式之适配器模式 结构型设计模式一个系统中不同实体(比如,类和对象)之间的关系,关注的是提供一种简单的对象组合方式来创造功能. 适配器模式( Adapter pattern)是一种结构 ...

  4. 运用sklearn进行线性判别分析(LDA)代码实现

    基于sklearn的线性判别分析(LDA)代码实现 一.前言及回顾 本文记录使用sklearn库实现有监督的数据降维技术——线性判别分析(LDA).在上一篇LDA线性判别分析原理及python应用(葡 ...

  5. windows下Nacos集群搭建与nginx集成

    前言: nacos集群至少需要三个(一般为奇数个)nacos实 例,其前面顶nginx,外界入口从nginx入 一.windows下Nacos集群搭建 将Nacos的解压包复制分成3份,分别是: na ...

  6. github Repository not found 解决办法

    git pull的时候遇到下面的报错. remote: Repository not found fatal: repository 'https://github.com/MyRepo/projec ...

  7. Jmeter 常用函数(11)- 详解 __TestPlanName

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 返回测试计划名称 语法格式 ${__T ...

  8. 精讲响应式WebClient第2篇-GET请求阻塞与非阻塞调用方法详解

    本文是精讲响应式WebClient第2篇,前篇的blog访问地址如下: 精讲响应式webclient第1篇-响应式非阻塞IO与基础用法 在上一篇文章为大家介绍了响应式IO模型和WebClient的基本 ...

  9. Azure Kubernetes Service 入门

    一,引言 上一节,我们使用Azure CLI 创建了Azure Resource Group 和 Azure Container Registry 资源,并且将本地的一个叫 “k8s.net.demo ...

  10. 第一篇 Scrum冲刺博客

    一.Alpha任务认领 冯荣新 任务 预计时间 搜索框 0.5h 首页轮播图 0.5h 分类导航 2h 商品列表 2h 商品详情轮播图 0.5h 商品底部工具栏 1h 购物车列表 1.5h 购物车工具 ...