在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 相关文章推荐
一个刚完成的layout(拖动流畅,不受iframe影响)
Aug 17 Javascript
JSON 入门指南 想了解json的朋友可以看下
Aug 26 Javascript
JS基础之undefined与null的区别分析
Aug 08 Javascript
将字符串中由空格隔开的每个单词首字母大写
Apr 06 Javascript
JavaScript 封装一个tab效果源码分享
Sep 15 Javascript
jquery制作属于自己的select自定义样式
Nov 23 Javascript
Sublime Text 3常用插件及安装方法
Dec 16 Javascript
移动端js触摸事件详解
Sep 18 Javascript
ztree简介_动力节点Java学院整理
Jul 19 Javascript
vue实现移动端图片裁剪上传功能
Aug 18 Javascript
vue实现全选和反选功能
Aug 31 Javascript
20个最常见的jQuery面试问题及答案
May 23 jQuery
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获取本周,上周,本月,上月,本季度日期的代码
2009/08/05 PHP
php设计模式 Bridge (桥接模式)
2011/06/26 PHP
PHP支持多种格式图片上传(支持jpg、png、gif)
2011/11/03 PHP
PHP函数http_build_query使用详解
2014/08/20 PHP
PHP实现将HTML5中Canvas图像保存到服务器的方法
2014/11/28 PHP
网页的标准,IMG不支持onload标签怎么办
2006/06/29 Javascript
javascript下查找父节点的简单方法
2007/08/13 Javascript
checkbox 复选框不能为空
2009/07/11 Javascript
详解强大的jQuery选择器之基本选择器、层次选择器
2012/02/07 Javascript
使用jquery mobile做幻灯播放效果实现步骤
2013/01/04 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
基于 Node.js 实现前后端分离
2016/04/23 Javascript
jQuery简单入门示例之用户校验demo示例
2016/07/09 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
Vue学习笔记进阶篇之单元素过度
2017/07/19 Javascript
解决Vue动态加载本地图片问题
2019/10/09 Javascript
js实现div色块碰撞
2020/01/16 Javascript
为react组件库添加typescript类型提示的方法
2020/06/15 Javascript
原生jQuery实现只显示年份下拉框
2020/12/24 jQuery
python编程线性回归代码示例
2017/12/07 Python
Python操作Redis之设置key的过期时间实例代码
2018/01/25 Python
pandas.dataframe按行索引表达式选取方法
2018/10/30 Python
pygame游戏之旅 按钮上添加文字的方法
2018/11/21 Python
Python进阶之@property动态属性的实现
2019/04/01 Python
python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)
2019/04/18 Python
python pygame实现滚动横版射击游戏城市之战
2019/11/25 Python
埃弗顿足球俱乐部官方网上商店:Everton Direct
2018/01/13 全球购物
房屋租赁协议书
2014/04/10 职场文书
小学生读书活动总结
2014/06/30 职场文书
三严三实对照检查材料
2014/09/22 职场文书
工程部文员岗位职责
2015/02/04 职场文书
2016反腐倡廉警示教育心得体会
2016/01/13 职场文书
《法国号》教学反思
2016/02/22 职场文书
nginx配置ssl实现https的方法示例
2021/03/31 Servers
nginx常用配置conf的示例代码详解
2022/03/21 Servers
Python中time与datetime模块使用方法详解
2022/03/31 Python