在JavaScript里防止事件函数高频触发和高频调用的方法


Posted in Javascript onSeptember 06, 2014

网页中JavaScript最基本的功能是监听或响应用户的动作,这非常的有用。用户的动作有些频率非常高,有的十分罕见。有些监听器函数的执行如闪电般完成,而有些繁重的会把浏览器拖死。拿浏览器窗口的resize事件来说,这种事件会在浏览器窗口大小的每一尺度变化都触发一次,如果监听器体量很大,你的浏览器很快就会被拖垮。

很显然,我们不能允许浏览器被拖垮,但我们又不能删除删除监听器。然而,我们可以限制函数调用的频度,弱化事件函数运行带来的影响。相对于让窗口的每一步size的变化都触发一次监听器函数,我们可以现在监听函数的触发的最小间隔必须大于多少毫秒,让它保持着合理的调用频道,确保不毁坏用户体验。有一个很好的js工具库叫做Underscore.js,它里面有一个简单的方法能让你轻松的创建降低事件函数触发频度的监听器。

JavaScript代码

降频监听器的代码很简单:

// 创建监听器

var updateLayout = _.debounce(function(e) {
 // Does all the layout updating here
}, 500); // 最低500毫秒运行一次
// Add the event listener

window.addEventListener("resize", updateLayout, false);

…这段Underscore.js代码底层实际上是用interval检查事件函数调用的频度:
// Returns a function, that, as long as it continues to be invoked, will not

// be triggered. The function will be called after it stops being called for

// N milliseconds. If `immediate` is passed, trigger the function on the

// leading edge, instead of the trailing.

_.debounce = function(func, wait, immediate) {

 var timeout;

 return function() {

  var context = this, args = arguments;

  var later = function() {

   timeout = null;

   if (!immediate) func.apply(context, args);

  };

  var callNow = immediate && !timeout;

  clearTimeout(timeout);

  timeout = setTimeout(later, wait);

  if (callNow) func.apply(context, args);

 };

};

代码并不是特别复杂,但用不着自己写也是一种幸福。这个debounce函数并没有依赖其他的Underscore.js函数,所以,你可以把这个方法添加到你喜欢的js工具库中,例如jQuery或MooTools,很容易:
// MooTools

Function.implement({

 debounce: function(wait, immediate) {

  var timeout, 

      func = this;

  return function() {

   var context = this, args = arguments;

   var later = function() {

    timeout = null;

    if (!immediate) func.apply(context, args);

   };

   var callNow = immediate && !timeout;

   clearTimeout(timeout);

   timeout = setTimeout(later, wait);

   if (callNow) func.apply(context, args);

  };

 }

});
// Use it!

window.addEvent("resize", myFn.debounce(500));

正如上面说的,窗口的resize事件是最常见的使用降频操作的地方,还有一个常用的地方是,根据用户的按键输入给出自动补全提示。我非常喜欢收集这样的代码片段,它们能轻松的让你的网站更高效。同时也推荐大家研究一下Underscore.js,里面提供了大量非常有用的函数。
Javascript 相关文章推荐
js的with语句使用方法
Sep 21 Javascript
jquery中的$(document).ready()与window.onload的区别
Nov 18 Javascript
防止页面被iframe(兼容IE,Firefox火狐)
Jul 04 Javascript
javascript开发技术大全-第3章 js数据类型
Jul 03 Javascript
js 获取页面高度和宽度兼容 ie firefox chrome等
May 14 Javascript
IE6兼容透明背景图片及解决方案
Aug 19 Javascript
微信开发 js实现tabs选项卡效果
Oct 28 Javascript
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
Nov 22 Javascript
完美的js图片轮换效果
Feb 05 Javascript
深入理解Webpack 中路径的配置
Jun 17 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
Aug 31 Javascript
Node与Python 双向通信的实现代码
Jul 16 Javascript
js获取页面传来参数的方法
Sep 06 #Javascript
用javascript关闭本窗口技巧小结
Sep 05 #Javascript
使用jquery解析XML示例代码
Sep 05 #Javascript
js实现按一下删除键删除整个单词附demo
Sep 05 #Javascript
JS获取当前网页大小以及屏幕分辨率等
Sep 05 #Javascript
JS来动态的修改url实现对url的增删查改
Sep 05 #Javascript
jQuery表格插件datatables用法总结
Sep 05 #Javascript
You might like
咖啡知识 咖啡养豆要养多久 排气又是什么
2021/03/06 新手入门
[FAQ]PHP中的一些常识:类篇
2006/10/09 PHP
PHP 字符串 小常识
2009/06/05 PHP
php 保留字列表
2012/10/04 PHP
php实现设计模式中的单例模式详解
2014/10/11 PHP
使用composer命令加载vendor中的第三方类库 的方法
2019/07/09 PHP
JS类的封装及实现代码
2009/12/02 Javascript
js Event对象的5种坐标
2011/09/12 Javascript
jQuery Jcrop插件实现图片选取功能
2011/11/23 Javascript
JQuery入门—JQuery程序的代码风格详细介绍
2013/01/03 Javascript
JS获取鼠标坐标的实例方法
2013/07/18 Javascript
jquery mobile页面跳转后样式丢失js失效的解决方法
2014/09/06 Javascript
JavaScript简单实现弹出拖拽窗口(二)
2016/06/17 Javascript
JavaScript创建对象_动力节点Java学院整理
2017/06/27 Javascript
JavaScript在控件上添加倒计时功能的实现代码
2017/07/04 Javascript
vue使用video.js进行视频播放功能
2019/07/18 Javascript
Vue 自定义指令实现一键 Copy功能
2019/09/16 Javascript
[01:09:24]Ti4开幕式
2014/07/19 DOTA
[40:48]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第二局
2016/02/28 DOTA
python进阶教程之异常处理
2014/08/30 Python
Python tkinter模块中类继承的三种方式分析
2017/08/08 Python
django中的setting最佳配置小结
2017/11/21 Python
python中使用 xlwt 操作excel的常见方法与问题
2019/01/13 Python
Python定义函数功能与用法实例详解
2019/04/08 Python
浅谈python之自动化运维(Paramiko)
2020/01/31 Python
Python操作MongoDb数据库流程详解
2020/03/05 Python
Jupyter notebook设置背景主题,字体大小及自动补全代码的操作
2020/04/13 Python
python 追踪except信息方式
2020/04/25 Python
python实现无边框进度条的实例代码
2020/12/30 Python
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
《月球之谜》教学反思
2014/04/10 职场文书
活动总结书
2014/05/08 职场文书
汉语专业毕业生自荐信
2014/07/06 职场文书
优秀教师个人总结
2015/02/11 职场文书
详解用Python把PDF转为Word方法总结
2021/04/27 Python
vue使用Google Recaptcha验证的实现示例
2021/08/23 Vue.js