在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 相关文章推荐
一个XML格式数据转换为图表的例子
Feb 09 Javascript
js播放wav文件(源码)
Apr 22 Javascript
js阻止冒泡及jquery阻止事件冒泡示例介绍
Nov 19 Javascript
jquery操作checked属性以及disabled属性的多种方法
Jun 20 Javascript
Javascript动态创建div的方法
Feb 09 Javascript
jquery的幻灯片图片切换效果代码分享
Sep 07 Javascript
Highcharts入门之简介
Aug 02 Javascript
vue中简单弹框dialog的实现方法
Feb 26 Javascript
JS高级技巧(简洁版)
Jul 29 Javascript
JS面试题中深拷贝的实现讲解
May 07 Javascript
js实现盒子移动动画效果
Aug 09 Javascript
Vue使用轮询定时发送请求代码
Aug 10 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
雄兵连:天使彦天使彦为爱折翼,彦和炙心同时念动的誓言!
2020/03/02 国漫
PHP过滤器 filter_has_var() 函数用法实例分析
2020/04/23 PHP
javascript 支持链式调用的异步调用框架Async.Operation
2009/08/04 Javascript
jQuery EasyUI API 中文文档 - Parser 解析器
2011/09/29 Javascript
jquery 设置元素相对于另一个元素的top值(实例代码)
2013/11/06 Javascript
js控制鼠标事件移动及移出效果显示
2014/10/19 Javascript
深入理解jQuery中的事件冒泡
2016/05/24 Javascript
JavaScript实现时间倒计时跳转(推荐)
2016/06/28 Javascript
jQuery EasyUI Draggable拖动组件
2017/03/01 Javascript
angular2系列之路由转场动画的示例代码
2017/11/09 Javascript
React-Router如何进行页面权限管理的方法
2017/12/06 Javascript
vue cli升级webapck4总结
2018/04/04 Javascript
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
2018/06/19 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
详解Vue基于vue-quill-editor富文本编辑器使用心得
2019/01/03 Javascript
Node.js中Koa2在控制台输出请求日志的方法示例
2019/05/02 Javascript
vue 对axios get pust put delete封装的实例代码
2020/01/05 Javascript
js判断在哪个浏览器打开项目的方法
2020/01/21 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
2020/09/11 Javascript
Python字符遍历的艺术
2008/09/06 Python
Python操作Excel之xlsx文件
2017/03/24 Python
python实现将excel文件转化成CSV格式
2018/03/22 Python
解决python-docx打包之后找不到default.docx的问题
2020/02/13 Python
基于spring boot 日志(logback)报错的解决方式
2020/02/20 Python
Django 解决阿里云部署同步数据库报错的问题
2020/05/14 Python
python 模拟登陆github的示例
2020/12/04 Python
python 装饰器重要在哪
2021/02/14 Python
通过canvas转换颜色为RGBA格式及性能问题的解决
2019/11/22 HTML / CSS
Electrolux伊莱克斯巴西商店:家用电器、小家电和配件
2018/05/23 全球购物
开办大学饮食联盟创业计划书
2014/01/29 职场文书
社会学专业求职信
2014/02/24 职场文书
抗洪救灾感谢信
2015/01/22 职场文书
员工自我评价范文
2015/03/11 职场文书
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS
java项目构建Gradle的使用教程
2022/03/24 Java/Android
MySQL的表级锁,行级锁,排它锁和共享锁
2022/07/15 MySQL