对于浏览器窗口大小改变的时候,来动态改变页面元素的大小,可以采用window的resize事件,实现代码:

  1. <script type="text/javascript">
  2. var n = 0;
  3. function resizehandler(){
  4. console.log(new Date().getTime());
  5. console.log(++n);
  6. }
  7.  
  8. window.onresize = resizehandler;
  9. </script>

功能能够实现,都是当我们用拖拽的方式改变浏览器大小的时候,控制台会不断打印执行resizehandler的函数的结果。

一次简单的拖拽会让resizehandler()函数执行很多次,实际在显示项目中resizehandler函数可能会很复杂,甚至会涉及到前后端的数据交互,所以一次拖拽执行很多次很明显是不能够接受的。

函数去抖

其实我们的本意只是窗口resize后页面做一些调整就可以了,而window的resize事件并不是在resize结束后才出发,具体的触发频率不是很清楚,但却在不停地调用,直到窗口大小不在变化。类似的机制还有鼠标的mousemove,都是在短时间内重复触发。

在《JavaScript高级程序设计》中有专门应对此问题的函数防抖

  1. function throttle(method, context){
  2. clearTimeout(method.tId);
  3. method.tId = setTimeout(function(){
  4. method.call(context);
  5. }, 500);
  6. }

原理很简单,利用定时器,让函数执行延迟500毫秒,在500毫秒内如果有函数又被调用则删除上一次的调用,这次调用500毫秒后执行,如此往复。这样刚才的代码可以改为:

  1. <script type="text/javascript">
  2. var n = 0;
  3. function resizehandler(){
  4. console.log(new Date().getTime());
  5. console.log(++n);
  6. }
  7.  
  8. function throttle(method, context){
  9. clearTimeout(method.tId);
  10. method.tId = setTimeout(function(){
  11. method.call(context);
  12. }, 500);
  13. }
  14.  
  15. window.onresize = function(){
  16. throttle(resizehandler, window);
  17. };
  18. </script>

这样的话执行就没有问题了。

函数防抖的另一种方法

预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个周期。

  1. function throttle(method, dalay){
  2. var timer = null;
  3. return function(){
  4. var context = this, args = arguments;
  5. clearTimeout(timer);
  6. timer = setTimeout(function(){
  7. method.apply(context, args);
  8. }, delay);
  9. }
  10. }

调用一下试试,一样的效果

  1. <script type="text/javascript">
  2. var n = 0;
  3. function resizehandler(){
  4. console.log(new Date().getTime());
  5. console.log(++n);
  6. }
  7.  
  8. function throttle(method, delay){
  9. var timer = null;
  10. return function(){
  11. var context = this, args = arguments;
  12. clearTimeout(timer);
  13. timer = setTimeout(function(){
  14. method.apply(context, args);
  15. }, delay);
  16. }
  17. }
  18.  
  19. window.onresize = throttle(resizehandler, 500); //这里因为返回函数句柄,不用包装函数了。
  20. </script>

比较

两种方法都是利用了setTimeout,不同的是第二种方法加入的函数延迟执行时间,这个在第一种方案中很容易也具有的功能,无非是加一个参数。

但是第一种方案把tId设为函数的一个变量保存,而第二种创建了闭包存储。个人觉得差距不大,很喜欢第一种,简单,高效。

新需求

百度首页输入自动提示一样的东西,我在text上绑定keyup事件,每次键盘弹起的时候自动提示,但是又不想提示那么频繁,于是我用了上面方法,但是悲剧了,只有挺直输入等500毫秒才会提示,在输入过程中根本就没有提示。看了一下代码,可不是嘛,只有用户会盲打,在500毫秒内按一下键盘,提示函数就会不断被延迟,这样只有停下来的时候才会提示,这就没有意义了。

能不能在函数节流的基础上间隔固定时间就执行一次?

函数节流

在网上搜了一下我们可以根据第二种下发(第一种函数拓展多个变量感觉有些不好)做些改动,添加一个参数作为到固定间隔必须执行。

  1. function throttle(method, delay, duration){
  2. var timer = null, begin = new Date();
  3. return function(){
  4. var context = this, args = arguments, current = new Date();
  5. clearTimeout(timer);
  6. if(current-begin >= duration){
  7. method.apply(context, args);
  8. begin = current;
  9. } else {
  10. timer = setTimeout(function(){
  11. method.apply(context, args);
  12. }, delay);
  13. }
  14. }
  15. }

这样每次我们判断间隔了够久,要是超过设置时间则立即执行一次,以刚才的例子试一试效果

  1. window.onresize = throttle(resizehandler, 100, 200);

这样,既没有频繁执行也没有就最后执行。

总结

对于函数节流在做动态响应用户行为方面有较大的使用频率,具体使用基础版本的函数节流还是改动版本的还要根据业务场景进行具体分析。

throttle和debounce均是通过减少实际逻辑处理过程的执行来提高事件处理函数运行性能的手段,并没有实质上减少事件的触发次数。 (逃)

JavaScript函数节流(throttle)与函数去抖(debounce)的更多相关文章

  1. [JavaScript] 函数节流(throttle)和函数防抖(debounce)

    js 的函数节流(throttle)和函数防抖(debounce)概述 函数防抖(debounce) 一个事件频繁触发,但是我们不想让他触发的这么频繁,于是我们就设置一个定时器让这个事件在 xxx 秒 ...

  2. javascript 函数节流 throttle 解决函数被频繁调用、浏览器卡顿的问题

    * 使用setTimeout index.html <html> <head> <meta charset="UTF-8"> <title ...

  3. js 函数节流throttle 函数去抖debounce

    1.函数节流throttle 通俗解释: 假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯: 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟: ...

  4. JS中的函数节流throttle详解和优化

    JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...

  5. 函数节流throttle和防抖debounce

    throttle 函数节流 不论触发函数多少次,函数只在设定条件到达时调用第一次函数设定,函数节流 1234567891011 let throttle = function(fn,intervalT ...

  6. js 高程 函数节流 throttle() 分析与优化

    在 js 高程 22.3.3章节 里看到了 函数节流 的概念,觉得给出的代码可以优化,并且概念理解可以清晰些,所以总结如下: 先看 函数节流 的定义,书上原话(斜体表示): 产生原因/适用场景: 浏览 ...

  7. 微信小程序:防止多次点击跳转(函数节流)

    场景 在使用小程序的时候会出现这样一种情况:当网络条件差或卡顿的情况下,使用者会认为点击无效而进行多次点击,最后出现多次跳转页面的情况,就像下图(快速点击了两次): 解决办法 然后从 轻松理解JS函数 ...

  8. 【Javascript函数】节流throttle和间隔控制dbounce

    一.throttle 函数节流,指把很小时间内触发的N多事件,节流成1个事件. 我们这里说的throttle就是函数节流的意思.再说的通俗一点就是函数调用的频度控制器,是连续执行时间间隔控制.主要应用 ...

  9. 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖

    前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...

  10. JS的函数节流(throttle)

    什么是函数节流? 介绍前,先说下背景.在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在 ...

随机推荐

  1. Identity Server4学习系列一

    一.前言 今天开始学习Identity Server4,顺便了解下.Net Core,以便于完善技术栈,最主要的是要跟上.Net的发展潮流,顺便帮助各位整理下官方文档,加上一些我自己对他的理解. 这是 ...

  2. FineBI学习系列之FineBI的Windows里安装步骤(图文详解)

    不多说,直接上干货! 先进入FineBI官网. http://www.finebi.com/product/download/  windows系统里FineBI的安装流程 1.从FineBI官网下载 ...

  3. springboot-32-使用mvc测试

    Spring Boot可以和大部分流行的测试框架协同工作:通过Spring JUnit创建单元测试:生成测试数据初始化数据库用于测试:Spring Boot可以跟BDD(Behavier Driven ...

  4. Andrew Ng机器学习课程笔记(三)之正则化

    Andrew Ng机器学习课程笔记(三)之正则化 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7365475.html 前言 ...

  5. CentOS7 下编译安装 Samba,什么是 SMB/CIFS 协议

    目录 一.关于 Samba 1. SMB 2. Samba 二.yum 安装 Samba 1. 安装 Samba 2. 查看版本 3. 查看配置文件 4. 启动服务 5. 本地客户端验证 6. Win ...

  6. B+树原理及mysql的索引分析

    转自:http://blog.csdn.net/qq_23217629/article/details/52512041 B+/-Tree原理 B-Tree介绍 B-Tree是一种多路搜索树(并不是二 ...

  7. mysql进行时

    1. 安装 参考 2. 远程连不上数据库 远程连接mysql时,提示“is not allowed to connect to this MySQL server” 解决(授权法): GRANT AL ...

  8. console 调试技巧

    前言 如果统计一番前端最常用的方法,那么 console.log 一定位列其中.无论你写的是原生 JS 亦或者是 JQuery.Vue等等,调试之时,都离不开 console.log 方法.但是,co ...

  9. MVC应用程序显示RealPlayer(rm)视频

    本篇博文是演示MVC应用程序显示RealPlayer视频. 客户端能观看到RealPlayer视频,前提条件是需要安装RealPlayer客户端,就是想看Falsh或理WMV视频一样,均要安装客户端或 ...

  10. AngularJS学习笔记(二)MVVM

    什么是MVVM MVVM模式是Model-View-ViewMode模式的简称. 由视图(View).视图模型(ViewModel).模型(Model)三部分组成,通过这三部分实现UI逻辑.呈现逻辑和 ...