在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获取IP和PcName(IE)在vs中可用
Aug 02 Javascript
含有CKEditor的表单如何提交
Jan 09 Javascript
jQuery避免$符和其他JS库冲突的方法对比
Feb 20 Javascript
在JavaScript中使用timer示例
May 08 Javascript
Javascript中关于Array.filter()的妙用详解
Dec 04 Javascript
微信小程序 连续旋转动画(this.animation.rotate)详解
Apr 07 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(下)
Apr 21 Javascript
自定义PC微信扫码登录样式写法
Dec 12 Javascript
Vue中的vue-resource示例详解
Nov 02 Javascript
微信小程序实现点击图片旋转180度并且弹出下拉列表
Nov 27 Javascript
小程序绑定用户方案优化小结
May 15 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
Nov 14 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
phpMyAdmin 安装配置方法和问题解决
2009/06/08 PHP
typecho插件编写教程(三):保存配置
2015/05/28 PHP
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
2016/12/14 PHP
php把文件设置为插件的技巧方法
2020/02/03 PHP
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
2006/09/22 Javascript
完美解决AJAX跨域问题
2013/11/01 Javascript
js获取当前地址 JS获取当前URL的示例代码
2014/02/26 Javascript
Javascript数据结构与算法之列表详解
2015/03/12 Javascript
js实现透明度渐变效果的方法
2015/04/10 Javascript
在AngularJS应用中实现一些动画效果的代码
2015/06/18 Javascript
javascript如何实现360度全景照片问题汇总
2016/04/04 Javascript
基于jquery实现表格内容筛选功能实例解析
2016/05/09 Javascript
jquery在vue脚手架中的使用方式示例
2017/08/29 jQuery
vue 中滚动条始终定位在底部的方法
2018/09/03 Javascript
JavaScript常见事件对象与操作实例总结
2019/01/05 Javascript
详解js 创建对象的几种方法
2019/03/08 Javascript
vue resource发送请求的几种方式
2019/09/30 Javascript
JS实现碰撞检测效果
2020/03/12 Javascript
Vue实现移动端拖拽交换位置
2020/07/29 Javascript
Python matplotlib画图实例之绘制拥有彩条的图表
2017/12/28 Python
使用Python监控文件内容变化代码实例
2018/06/04 Python
详解Python 协程的详细用法使用和例子
2018/06/15 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
在主流系统之上安装Pygame的方法
2020/05/20 Python
用CSS3写的模仿iPhone中的返回按钮
2015/04/04 HTML / CSS
高级护理专业毕业生推荐信
2013/12/25 职场文书
毕业生自我鉴定实例
2014/01/21 职场文书
代领毕业证委托书
2014/08/02 职场文书
大学军训自我鉴定大全
2014/09/18 职场文书
2014年医院后勤工作总结
2014/12/06 职场文书
2014社区健康教育工作总结
2014/12/16 职场文书
导游词之北京明十三陵
2019/10/28 职场文书
MySQL中in和exists区别详解
2021/06/03 MySQL
python中subplot大小的设置步骤
2021/06/28 Python
python中的sys模块和os模块
2022/03/20 Python