在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的千分位算法实现思路
Jul 31 Javascript
JS中判断null、undefined与NaN的方法
Mar 26 Javascript
Javascript学习笔记之 对象篇(三) : hasOwnProperty
Jun 24 Javascript
javascript时间函数大全
Jun 30 Javascript
jQuery 处理页面的事件详解
Jan 20 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
Mar 30 Javascript
AngularJS ionic手势事件的使用总结
Aug 09 Javascript
JavaScript实现图片本地预览功能【不用上传至服务器】
Sep 20 Javascript
如何利用ES6进行Promise封装总结
Feb 11 Javascript
Node.js API详解之 net模块实例分析
May 18 Javascript
微信小程序清空输入框信息与实现屏幕往上滚动的示例代码
Jun 23 Javascript
openlayers实现地图测距测面
Sep 25 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
一个php作的文本留言本的例子(五)
2006/10/09 PHP
php封装的验证码类分享
2017/02/26 PHP
PHP学习记录之常用的魔术常量详解
2019/12/12 PHP
FireFox中textNode分片的问题
2007/04/10 Javascript
flash调用js中的方法,让js传递变量给flash的办法及思路
2013/08/07 Javascript
jquery阻止后续事件只执行第一个事件
2014/07/24 Javascript
基于JS实现textarea中获取动态剩余字数的方法
2016/05/25 Javascript
Canvas实现放射线动画效果
2017/02/15 Javascript
关于vue.js发布后路径引用的问题解决
2017/08/15 Javascript
浅谈关于.vue文件中style的scoped属性
2017/08/19 Javascript
一步步教你利用Docker设置Node.js
2018/11/20 Javascript
使用VueCli3+TypeScript+Vuex一步步构建todoList的方法
2019/07/25 Javascript
[05:09]2016国际邀请赛中国区预选赛淘汰赛首日精彩回顾
2016/06/29 DOTA
用python实现的去除win下文本文件头部BOM的代码
2013/02/10 Python
Python 中迭代器与生成器实例详解
2017/03/29 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
2018/01/05 Python
利用Python如何批量更新服务器文件
2018/07/29 Python
python3 读取Excel表格中的数据
2018/10/16 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
python爬虫基础教程:requests库(二)代码实例
2019/04/09 Python
基于tensorflow指定GPU运行及GPU资源分配的几种方式小结
2020/02/03 Python
用 Django 开发一个 Python Web API的方法步骤
2020/12/03 Python
Hertz荷兰:荷兰和全球租车
2018/01/07 全球购物
软件生产职位结构化面试主要考察要素及面试题库
2015/06/12 面试题
车间班组长岗位职责
2013/11/13 职场文书
网吧收银员岗位职责
2013/12/14 职场文书
进口业务员岗位职责
2014/04/06 职场文书
我爱家乡演讲稿
2014/09/12 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
2014年计划生育工作总结
2014/11/14 职场文书
2014年文明创建工作总结
2014/11/25 职场文书
电影建国大业观后感
2015/06/01 职场文书
2015国庆66周年宣传语
2015/07/14 职场文书
《山中访友》教学反思
2016/02/24 职场文书
Pytorch反向传播中的细节-计算梯度时的默认累加操作
2021/06/05 Python
微软官方消息,在 2023 年 4 月 11 日之后微软将不再为 Office 2013 和 Skype for Business 2015 提供安全更新
2022/04/21 数码科技