在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获取scrollHeight问题想到的标准问题
May 27 Javascript
深入理解JavaScript高级之词法作用域和作用域链
Dec 10 Javascript
深入理解JS中的substr和substring
Apr 26 Javascript
javascript中的深复制详解及实例分析
Dec 29 Javascript
javascript设计模式之中介者模式学习笔记
Feb 15 Javascript
jQuery DOM节点的遍历方法小结
Aug 15 jQuery
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
Aug 19 Javascript
javascript的this关键字详解
May 20 Javascript
自定义Vue组件打包、发布到npm及使用教程
May 22 Javascript
vue中beforeRouteLeave实现页面回退不刷新的示例代码
Nov 01 Javascript
Node.js web 应用如何封装到Docker容器中
Sep 01 Javascript
微信小程序实现左滑删除效果
Nov 18 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
destoon实现不同会员组公司名称显示不同的颜色的方法
2014/08/22 PHP
php从memcache读取数据再批量写入mysql的方法
2014/12/29 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
详解关于php的xdebug配置(编辑器vscode)
2019/01/29 PHP
jquery 单击li防止重复加载的实现代码
2010/12/24 Javascript
javascript学习笔记(十七) 检测浏览器插件代码
2012/06/20 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
2012/09/14 Javascript
JavaScript事件 "事件对象"的注意要点
2016/01/14 Javascript
Nodejs爬虫进阶教程之异步并发控制
2016/02/15 NodeJs
Nodejs中的this详解
2016/03/26 NodeJs
JavaScript  cookie 跨域访问之广告推广
2016/04/20 Javascript
React.js入门实例教程之创建hello world 的5种方式
2016/05/11 Javascript
正则表达式(语法篇推荐)
2016/06/24 Javascript
JavaScript实现复制文章自动添加版权
2016/08/02 Javascript
JS实现简单的tab切换选项卡效果
2016/09/21 Javascript
bootstrap实现动态进度条效果
2017/03/08 Javascript
js实现字符全排列算法的简单方法
2017/05/01 Javascript
vue中axios请求的封装实例代码
2019/03/23 Javascript
typescript nodejs 依赖注入实现方法代码详解
2019/07/21 NodeJs
jQuery--遍历操作实例小结【后代、同胞及过滤】
2020/05/22 jQuery
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
详解Python中的序列化与反序列化的使用
2015/06/30 Python
Python实现字符串格式化的方法小结
2017/02/20 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
2018/02/10 Python
django输出html内容的实例
2018/05/27 Python
Django中使用Celery的方法示例
2018/11/29 Python
对Xpath 获取子标签下所有文本的方法详解
2019/01/02 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
Python3实现的回文数判断及罗马数字转整数算法示例
2019/03/27 Python
世界上获奖最多的手机镜头:Olloclip
2018/03/03 全球购物
OLEDBConnection和SQLConnection有什么区别
2013/05/31 面试题
好军嫂事迹材料
2014/01/15 职场文书
《秋游》教学反思
2014/04/24 职场文书
好听的队名和口号
2014/06/09 职场文书
生活部的活动方案
2014/08/19 职场文书
优秀创业计划书分享
2019/07/19 职场文书