博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript函数节流
阅读量:6244 次
发布时间:2019-06-22

本文共 2154 字,大约阅读时间需要 7 分钟。

最近在做网页的时候有个需求,就是浏览器窗口改变的时候需要改一些页面元素大小,于是乎很自然的想到了window的resize事件,于是乎我是这么写的

    Throttle    

 

功能倒是实现了,但是我拖拽的方式改变浏览器窗口大小的时候看了下控制台

 

没错,简单的一个拖拽让我的resizeHandler()方法执行了52次,这完全不是我想要的效果,实际上我的resizeHandler()方法的代码很复杂,甚至会使用ajax向服务器发送请求,要是简单的一次改变窗口大小就要调用52次这还了得

函数节流

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

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

function throttle(method,context){            clearTimeout(method.tId);            method.tId=setTimeout(function(){                method.call(context);            },500);        }

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

拖拽一下试试,果真只执行了一次

另一种做法

网上还有一种函数节流方案,它是这么做的

function throttle(method,delay){            var timer=null;            return function(){                var context=this, args=arguments;                clearTimeout(timer);                timer=setTimeout(function(){                    method.apply(context,args);                },delay);            }        }

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

比较

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

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

新需求

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

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

小改动

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

function throttle(method,delay,duration){            var timer=null, begin=new Date();            return function(){                var context=this, args=arguments, current=new Date();;                clearTimeout(timer);                if(current-begin>=duration){                     method.apply(context,args);                     begin=current;                }else{                    timer=setTimeout(function(){                        method.apply(context,args);                    },delay);                }            }}

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

window.οnresize=throttle(resizehandler,100,200);

果真既没有频繁执行也没有就最后执行

 

转载于:https://www.cnblogs.com/dolphinX/p/3403821.html

你可能感兴趣的文章
iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)
查看>>
Java集合框架中的快速失败(fail—fast)机制
查看>>
特殊的上下文选择符
查看>>
iphone-common-codes-ccteam源代码 CCUIApplication.m
查看>>
展开和折叠GridView行
查看>>
SharePoint PeopleEditor 控件的使用
查看>>
删除mysql__转
查看>>
python+selenium的使用
查看>>
python2.7中MySQLdb的安装与使用详解
查看>>
知乎技术方案初探[转]
查看>>
Java中的Thread与Runnable的区别
查看>>
2018/11/29 一个64位操作系统的设计与实现 02 (安装nasm)
查看>>
python(48):re.split 多分隔符
查看>>
nyoj746 整数划分(四)
查看>>
FZU 1894 志愿者选拔 单调队列
查看>>
asp.net的Request.ServerVariables参数说明
查看>>
eclipse中配置maven
查看>>
get方法与post方法的使用
查看>>
一步一步学习SignalR进行实时通信_1_简单介绍
查看>>
SPSS—回归—多元线性回归(转)
查看>>