在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 相关文章推荐
ExtJs之带图片的下拉列表框插件
Mar 04 Javascript
AngularJS控制器详解及示例代码
Aug 16 Javascript
基于AngularJS前端云组件最佳实践
Oct 20 Javascript
js上下视差滚动简单实现代码
Mar 07 Javascript
TypeScript入门-基本数据类型
Mar 28 Javascript
Kotlin学习第一步 kotlin语法特性
May 25 Javascript
js传递数组参数到后台controller的方法
Mar 29 Javascript
eslint 的三大通用规则详解
May 16 Javascript
vue动态配置模板 'component is'代码
Jul 04 Javascript
Js on及addEventListener原理用法区别解析
Jul 11 Javascript
vue打包静态资源后显示空白及static文件路径报错的解决
Sep 02 Javascript
JavaScript继承的三种方法实例
May 12 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
Uncaught exception com_exception with message Failed to create COM object
2012/01/11 PHP
php去除换行符的方法小结(PHP_EOL变量的使用)
2013/02/16 PHP
简单了解将WordPress中的工具栏移到底部的小技巧
2015/12/31 PHP
PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】
2017/01/13 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
HTML颜色选择器实现代码
2010/11/23 Javascript
JQuery入门——事件切换之hover()方法应用介绍
2013/02/05 Javascript
jquery遍历checkbox的注意事项说明
2014/02/21 Javascript
减少访问DOM的次数提升javascript性能
2014/02/24 Javascript
jquery操作checkbox示例分享
2014/07/21 Javascript
项目实践一图片上传之form表单还是base64前端图片压缩(前端图片压缩)
2016/07/28 Javascript
Jquery Easyui搜索框组件SearchBox使用详解(19)
2016/12/17 Javascript
移动端界面的适配
2017/01/11 Javascript
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
Vue项目中跨域问题解决方案
2018/06/05 Javascript
vue实现动态添加数据滚动条自动滚动到底部的示例代码
2018/07/06 Javascript
jQuery利用cookie 实现本地收藏功能(不重复无需多次命名)
2019/11/07 jQuery
详解vue-router的Import异步加载模块问题的解决方案
2020/05/13 Javascript
解决在Vue中使用axios POST请求变成OPTIONS的问题
2020/08/14 Javascript
jQuery实现图片切换效果
2020/10/19 jQuery
[01:36:57]【09DOTA2第一视角】小骷髅
2014/04/16 DOTA
python爬取拉勾网职位数据的方法
2018/01/24 Python
利用python为运维人员写一个监控脚本
2018/03/25 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
Python实现查看系统启动项功能示例
2018/05/10 Python
Django实现跨域的2种方法
2019/07/31 Python
python 矢量数据转栅格数据代码实例
2019/09/30 Python
使用phonegap获取设备的一些信息方法
2017/03/31 HTML / CSS
html5使用canvas压缩图片的示例代码
2018/09/11 HTML / CSS
旅游项目开发策划书
2014/01/18 职场文书
党的群众路线教育实践活动批评与自我批评
2014/02/16 职场文书
服装设计专业自荐信
2014/06/17 职场文书
公司董事长助理工作职责
2014/07/12 职场文书
导游词之介休绵山
2019/12/31 职场文书
JavaScript实现一键复制内容剪贴板
2022/07/23 Javascript
SqlServer常用函数及时间处理小结
2023/05/08 SQL Server