在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 相关文章推荐
jquery 打开窗口返回值实现代码
Mar 04 Javascript
一些主流JS框架中DOMReady事件的实现小结
Feb 12 Javascript
深入理解javascript学习笔记(一) 编写高质量代码
Aug 09 Javascript
在AngularJS中使用AJAX的方法
Jun 17 Javascript
js省市县三级联动效果实例
Apr 15 Javascript
JavaScript实现垂直滚动条效果
Jan 18 Javascript
用js将long型数据转换成date型或datetime型的实例
Jul 03 Javascript
JavaScript生成指定范围随机数和随机序列的方法
May 05 Javascript
微信小程序开发常见问题及解决方案
Jul 11 Javascript
jquery实现掷骰子小游戏
Oct 24 jQuery
Vue中图片Src使用变量的方法
Oct 30 Javascript
记一次vue跨域的解决
Oct 21 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实现统计所有字符在字符串中出现次数的方法
2017/10/17 PHP
php使用array_chunk函数将一个数组分割成多个数组
2018/12/05 PHP
Laravel框架自定义公共函数的引入操作示例
2019/04/16 PHP
Javascript模板技术
2007/04/27 Javascript
更正确的asp冒泡排序
2007/05/24 Javascript
javascript不同页面传值的改进版
2008/09/30 Javascript
Jquery 学习笔记(一)
2009/10/13 Javascript
22点关于jquery性能优化的建议
2014/05/28 Javascript
javascript中不易分清的slice,splice和split三个函数
2016/03/29 Javascript
Angular 常用指令实例总结整理
2016/12/13 Javascript
vue+vue-validator 表单验证功能的实现代码
2017/11/13 Javascript
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
微信小程序如何调用json数据接口并解析
2019/06/29 Javascript
微信小程序实现多行文字超出部分省略号显示功能
2019/10/23 Javascript
[42:20]2014 DOTA2华西杯精英邀请赛5 24 DK VS NewBee
2014/05/25 DOTA
Python第三方库的安装方法总结
2016/06/06 Python
教你用python3根据关键词爬取百度百科的内容
2016/08/18 Python
Python脚本实时处理log文件的方法
2016/11/21 Python
Python实现的维尼吉亚密码算法示例
2018/04/12 Python
python中从str中提取元素到list以及将list转换为str的方法
2018/06/26 Python
Django命名URL和反向解析URL实现解析
2019/08/09 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
Python 实现训练集、测试集随机划分
2020/01/08 Python
python实现猜拳游戏项目
2020/11/30 Python
python中常用的数据结构介绍
2021/01/12 Python
Python实现Excel自动分组合并单元格
2021/02/22 Python
中国首家奢侈品O2O网购平台:第五大道奢侈品网
2017/12/14 全球购物
介绍一下代理模式(Proxy)
2014/10/17 面试题
大学生求职简历的自我评价
2013/10/21 职场文书
幼儿园家长评语
2014/02/10 职场文书
资金主管岗位职责范本
2014/03/04 职场文书
学校四风问题对照检查材料思想汇报
2014/09/26 职场文书
调解协议书范本
2016/03/21 职场文书
Python OpenCV 图像平移的实现示例
2021/06/04 Python
SpringBoot连接MySQL获取数据写后端接口的操作方法
2021/11/02 MySQL
R9700摩机记
2022/04/05 无线电