浅谈javascript函数节流
浅谈javascript函数节流
什么是函数节流?
函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等等事情,那么这时候窗口缩放的时候,有可能连续发多个请求,这并不是我们想要的,或者是说我们常见的鼠标移入移出tab切换效果,有时候连续且移动的很快的时候,会有闪烁的效果,这时候我们就可以使用函数节流来操作。大家都知道,DOM的操作会很消耗或影响性能的,如果是说在窗口缩放的时候,为元素绑定大量的dom操作的话,会引发大量的连续计算,比如在IE下,过多的DOM操作会影响浏览器性能,甚至严重的情况下,会引起浏览器崩溃的发生。这个时候我们就可以使用函数节流来优化代码了~
函数节流的基本原理:
使用一个定时器,先延时该函数的执行,比如使用setTomeout()这个函数延迟一段时间后执行函数,如果在该时间段内还触发了其他事件,我们可以使用清除方法 clearTimeout()来清除该定时器,再setTimeout()一个新的定时器延迟一会儿执行。
我们先来看一个简单的window.resize的demo例子,比如我先定义一个全局变量count=0;当我触发一次window.resize的时候,该全局变量count++; 我们来看看在控制台中打印出count的效果;JS代码如下:
var count = 0;
window.onresize = function(){
count++;
console.log(count);
}
执行截图效果如下:
如上resize的代码,简单的缩放一次就打印出多次,这并不是我们想要的效果,这是简单的测试,那如果我们换成ajax请求的话,那么就会缩放一次窗口会连续触发多次ajax请求,下面我们试着使用函数节流的操作试试一下;
函数节流的第一种方案封装如下:
function throttleFunc(method,context){
clearTimeout(method.tId);
method.tId = setTimeout(function(){
method.call(context);
},100);
}
我们再来封装一下窗口缩放的demo
var count = 0;
function myFunc() {
count++;
console.log(count);
}
window.onresize = function(){
throttleFunc(myFunc);
}
function throttleFunc(method,context){
clearTimeout(method.tId);
method.tId = setTimeout(function(){
method.call(context);
},100);
}
如上代码,我们再来看看效果,窗口缩放和放大效果会看到,只执行了一次;打印了一次。
上面的代码使用一个定时器每隔100毫秒执行一次;
我们也可以使用闭包的方法对上面的函数进行再封装一下;
函数节流的第二种封装方法如下:
function throttle(fn, delay){
var timer = null;
return function(){
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(context, args);
}, delay);
};
};
上面第二种方案是使用闭包的方式形成一个私有的作用域来存放定时器timer,第二种方案的timer是通过传参数的形式引入的。
调用demo代码如下:
var count = 0;
function myFunc() {
count++;
console.log(count);
}
var func = throttle(myFunc,100);
window.onresize = function(){
func();
}
function throttle(fn, delay){
var timer = null;
return function(){
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(context, args);
}, delay);
};
};
函数节流的基本思想是:就是想让一个函数不要执行的太频繁,减少一些过快的来节流函数,比如当我们改变窗口缩放的时候,浏览器的间隔有可能是16ms,这是浏览器自带的时间间隔,我们无法改变,而我们通过节流的方式可以试着改变一下这个间隔,尽量稍微延长下这个调用时间,因此我们可以封装如下函数:
函数节流的第三种封装方法
function throttle3(fn,delay,runDelay){
var timer = null;
var t_start;
return function(){
var context = this,
args = arguments,
t_cur = new Date();
timer && clearTimeout(timer);
if(!t_start) {
t_start = t_cur;
}
if(t_cur - t_start >= runDelay) {
fn.apply(context,args);
t_start = t_cur;
}else {
timer = setTimeout(function(){
fn.apply(context,args);
},delay);
}
}
}
调用demo如下:
var count = 0;
function myFunc() {
count++;
console.log(count);
}
var func = throttle3(myFunc,50,100);
window.onresize = function(){
func();
}
function throttle3(fn,delay,runDelay){
var timer = null;
var t_start;
return function(){
var context = this,
args = arguments,
t_cur = new Date();
timer && clearTimeout(timer);
if(!t_start) {
t_start = t_cur;
}
if(t_cur - t_start >= runDelay) {
fn.apply(context,args);
t_start = t_cur;
}else {
timer = setTimeout(function(){
fn.apply(context,args);
},delay);
}
}
}
上面的第三个函数是封装后的函数,有三个参数,我们可以自己设置触发事件的时间间隔,则意味着,如上代码50ms连续调用函数,后一个调用会把前一个调用的等待处理掉,但每隔100ms会至少执行一次,具体使用哪一种方式只要看自己的权衡,但是我个人觉得第二种封装函数的方式够我们使用的,当然据说第三种方式性能更好~
浅谈javascript函数节流的更多相关文章
- [转载]浅谈JavaScript函数重载
原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...
- 再谈javascript函数节流
之前写过但是不记得在哪了,今天同事要一个滑到页面底部加载更多内容的效果,又想起了这玩意儿,确实挺实用和常用的,谨此记之. 函数节流从字面上的意思就是节约函数的执行次数,其实现的主要思想是通过定时器阻断 ...
- [转]浅谈javascript函数劫持
转自:Ph4nt0m Security Team 这么多年了,现在学习依然还是有很多收货,向前辈致敬.转载一方面是自己存档一份,另一方面是让更多喜欢安全的人一同学习. ================ ...
- 浅谈JavaScript 函数作用域当中的“提升”现象
在JavaScript当中,定义变量通过var操作符+变量名.但是不加 var 操作符,直接赋值也是可以的. 例如 : message = "hello JavaScript ! " ...
- 浅谈javascript函数,变量声明及作用域
javascript函数跟变量的声明.作用域这些概念网上都已经讲烂了. 这里写个博客,也相当于做个笔记. 变量声明 首先看个例子: var globalVar = "gv"; fu ...
- 浅谈javascript函数执行过程
javascript函数执行过程: 1. 为函数创建一个执行环境 2. 复制函数的 [[scopes]] 属性中的对象构建起执行环境的作用链域 3. 创建函数活动对象并推入执行环境作用链域的前端 4. ...
- 浅谈JS函数节流及应用场景
说完防抖,下面我们讲讲节流,规矩就不说了,先上代码: <!DOCTYPE html> <html lang="en"> <head> <m ...
- 浅谈JavaScript函数
JavaScript作为一种基于对象(非严格面向对象)的语言,函数在JS中的地位非同一般:用函数声明类和对象.甚至函数本身也是对象. 一.函数的三种声明方式辨析. 1.function命令 funct ...
- 浅谈JavaScript函数重载
上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都很难,根本回答不上来.不过那天晚上,还是很惊喜的接到了HR面电话.现在HR ...
随机推荐
- HNOI2016(BZOJ4542) 大数
HNOI2016 Day2 T3 大数 Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P ...
- Android成长日记-WebView使用
在App中有时候会看到一些页面是以网页的形式展示,其原理就是运用了WebView,下面予以讲述WebView 1. 使用Intent调用系统浏览器或者第三方浏览器打开网页 调用系统浏览器打开页面 Ur ...
- array数组加过滤
var array = new Array(); array.push(0); array.push(1); array.push(2); var arr = array.filter(functio ...
- androidstudio 常用快捷键
ctrl+p 查看需要输入的函数列表 ctrl+h 查看继承关系 ctrl +w 选择一个,一行,一段. alter+enter 内容助理 ctrl+q 查看方法注解 相当于 hover ...
- spring jdbc分离数据库代码和java代码
读取配置文件类 package com.eshore.ismp.contract.sql; import java.io.FileInputStream; import java.io.FileNot ...
- 【Beta版本】冲刺-Day6
队伍:606notconnected 会议时间:12月14日 目录 一.行与思 二.站立式会议图片 三.燃尽图 四.代码Check-in 一.行与思 张斯巍(433) 今日进展:修改界面规范,应用图标 ...
- 使用Wireshark 抓取数据包
Wireshark 是一个网络封包分析软件.网络封包分析软件的功能是获取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直接与网卡进行数据报文交换. 一 ...
- NOIp2010 关押罪犯
二分+2-SAT 先预处理出所有的v,然后离散化一下,在那个的基础上二分,对于每次二分出的值约束边权超过所二分出的边权的两点. //OJ 1322 //by Cydiater //2015.8.26 ...
- mybatis的批量删除
公司工程用的是Mybatis的example的类,自动生成了对数据库的操作,批量操作的今天用到了,两种方式,一种需要拓展它生成的类,另一种自带的. 批量删除的id是以集合List传递 id以List& ...
- glade2支持C++代码的输出(1)
开发了一个基类,用于支持GTK2的信号回调 见BaseObject.zip 为了便于快速通过glade设计界面,并生成相应的C++代码,我对glade-2 2.12.2的代码进行了修改 原始代码:gl ...