您的位置:首页 > Web前端

前端节流和防抖(上)

2020-04-10 19:11 519 查看

节流和防抖(上)

节流和防抖,共性都是对短时间会大量触发浏览器事件的优化

防抖

//防抖debounce
/* 在用户触发事件的时间间隔小于(规定时间段)时候才触发函数
简单来说,就是用户只要触发事件时间比设定的时间段短,那函数就不会触发
个人粗鄙理解(只要我动得够快,你就不会触发)
*/
<input class="inp" type="text" />
//应用场景,我要在用户输入停止1s后,才打印输出用户的输入内容
// 防抖函数 (第一版,简易版)
function debounce(fn, delay) {
let timer = null;
return function () {
// 如果timer存在,清除
if (timer) {
clearTimeout(timer)
}
// 开规定事件的定时器
timer = setTimeout(() => {
fn();
}, delay)
}
}

//获取元素
let input = document.querySelector('.inp');
//展示
function showVal() {
console.log('input .value', input .value);
}

//绑定事件
input.oninput = debounce(showVal, 1000);
但是简易版中,使用this的时候就会有问题
function showVal() {
console.log('this.value', this.value); //输出undefined
}
//原因在于在闭包返回函数后,this已经指向了window

//解决方法
// 防抖函数 (第二版,修正this版)
function debounce(fn, delay) {
let timer = null;
return function () {

//1.在这里保存函数执行的上下文环境
const content = this;

// 如果timer存在,清除
if (timer) {
clearTimeout(timer)
}
// 开规定事件的定时器
timer = setTimeout(() => {

//2.在这里改变函数执行的上下文环境
fn.call(this);
}, delay)
}
}
在第二版中,我们修正了this,但是对于事件参数并没有修正
function showVal(e) {
console.log(e.target);
}

使用第二部的代码执行上面函数时候会报错

这个时候就需要第三版

// 防抖函数 (第三版,修正event参数)
function debounce(fn, delay) {
let timer = null;
return function () {

const content = this;
//1.在这里保存函数的参数列表
const args = arguments;

// 如果timer存在,清除
if (timer) {
clearTimeout(timer)
}
// 开规定事件的定时器
timer = setTimeout(() => {

//2.在这里把函数的参数列表作为参数传递进去
fn.apply(this,args);
}, delay)
}
}
在这里就会有同学问了,为什么在第三版用apply,不用call呢?

我们可以输出arguments看一下=_=

很明显arguments是一个参数列表

//函数call和apply都是改变函数的指向,但是参数的传递不一样
fn.call(content,param1,param2...)
fn.apply(conent,[param1,param2...])
//两者的第一个参数都是函数执行的上下文环境,但是后面call是一个个的参数传递,apply是一个参数列表的形势传递

//第三部 使用call传递也是可以的
fn.apply(this,...args); //使用es6 的...语法将参数列表解构出来

  • 点赞
  • 收藏
  • 分享
  • 文章举报
chenjinyu_lxl 发布了11 篇原创文章 · 获赞 0 · 访问量 109 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: