J51 函数的防抖和节流

157 阅读2分钟

1.函数的防抖

函数的防抖(debounce):1.不是某个时间触发就去执行函数,而是在指定的时间隔内,执行一次,减少函数执行的次数;2.用户频繁触发的时候,我们只识别一次,第一次识别不要了,只要最后一次

  • 1.未防抖的效果
//在控制台查看防抖
   window.onscroll=function(){
        console.log(“ok”);//=>F12 滑动会出现很多的ok
    }
//1.防抖的效果
//2.安装:npm i underscore
//3.使用:打开控制台 滑动页面 间隔相应事件出现相应的滑动次数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">        
        <title>函数的防抖</title>
        <style>
    html,body{
        height:500%;
        background:-webkit-linear-gradient(top left,lightblue,pink,blue);
    }
    </style>
    </head>
    <body>
     <script src="node_modules/underscore/underscore.js"></script>

   <script>
    let count=0;
    function fn() {
        console.log(++count);
        console.log('ok');
    }
    let lazyFn= _.debounce(fn,40,true)
        window.onscroll=lazyFn;
   </script>
    </body>
</html>
  • 3.需求:校验用于输入的文本是否都是数字,合法 就在控制台输出是否合法即可
<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>函数的防抖</title>
</head>
<body>
<input type="text" id='inp'>
    <script>
    //防抖 需求:校验用于输入的文本是否都是数字,合法 就在控制台输出是否合法即可
    let inp=document.querySelector("#inp");
    let timer=null;
    inp.oninput=function(){
        //只要input框的内容发生改变,就会触发这个函数
        clearTimeout(timer);//内容没改变一次,都会把上一次形成的定时器给清楚
       timer=setTimeout(() => {
            console.log(this.value)
        }, 500);
    }
    </script>
</body>
</html>

//使用:1.预览页面 2.打开控制台 3.输入框输入内容,输入完成后在控制台显示,输入的内容
  • 4.防抖的封装
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">        
        <title>函数的防抖</title>
        <style>
    html,body{
        height:500%;
        background:-webkit-linear-gradient(top left,lightblue,pink,blue);
    }
    </style>
    </head>
    <body>
   <script>
    //封装一个防抖函数
    /* debounce:函数防抖
    * @params
        func:要执行的函数
        wait:间隔等待时间
        immediate:在开始边界还是结束边界触发执行(true是在开始边界)
        @return 可被调用的函数
    */
    function debounce(func,wait,immediate){
    let result=null;
        timeout=null;
        return function(...args){
        let context=this;
        //是不是现在执行
        now=immediate && !timeout;
        clearTimeout(timeout);//=>在设置新的定时器之前,
        //我们要把之前设置的定时器删除,因为防抖的目的是等待时间内,只执行一次
        timeout=setTimeout(() => {
            if(!immediate)result=func.call(context,...args);
            clearTimeout(timeout);
            timeout=null;
        }, wait);
        if(now)result=func.call(context,...args);
        }
    }

    let count=0;
    function fn() {
        console.log(++count);
    }
    let lazyFn= debounce(fn,40,true)
        window.onscroll=lazyFn;

   </script>

    </body>
</html>
//1.使用:预览页面  打开控制台  滑动页面可看出效果

2.函数的节流

函数的节流(throttle):为了缩减执行的频率,但不像防抖一样,一定时间内只能执行一次,而是一定时间内能执行多次

//1.防抖的效果
//2.安装:npm i underscore
//3.使用:打开控制台 滑动页面 间隔出现滑动的次数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">        
        <title>函数的防抖</title>
        <style>
    html,body{
        height:500%;
        background:-webkit-linear-gradient(top left,lightblue,pink,blue);
    }
    </style>
    </head>
    <body>
     <script src="node_modules/underscore/underscore.js"></script>
   <script> 

    let count=0;
    function fn() {
        console.log(++count);
    }
    let lazyFn=_.throttle(fn,40,true)
        window.onscroll=lazyFn;

   </script> 
    </body>
</html>
  • 2.文本框的节流
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>函数的节流</title>
</head>
<body>
<input type="text" id='inp'>
<script>  
//节流
let flag=true;
inp.oninput=function(){
    //当这个函数第一次执行的时候,flag是true,所以能走到判断下边的代码
    //当这个函数在500毫秒之内再次执行的时候,由于flag还是false,所以还是走不到判断下边的代码,
    //当过了500毫秒之后,flag重新变成了true,这时这个函数在执行的话,就可以走到下边代码,
    //下边的代码,又把flag编程false 也就是说下一次能执行判断下边的代码 还得等500毫秒
    if(flag===false) return;
    flag=false;
    console.log(this.value)
    setTimeout(()=>{
        flag=true;
    },500);
}
</script>
</body>
</html>

//使用:1.预览页面 2.打开控制台 3.输入框输入内容,输入时,会隔一段事件控制台出现输入的内容,连续输入,会500s显示一次
  • 3.节流的封装
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">        
    <title>函数的节流</title>
    <style>
html,body{
    height:500%;
    background:-webkit-linear-gradient(top left,lightblue,pink,blue);
}
</style>
</head>
<body>

<script>
/*封装节流
* throttle:函数节流是为了缩减执行频率,当达到了一定的时间间隔就会执行一次
*   @params
*      func:需要执行的函数
*      wait:设置的间隔时间
*   @return
*      返回可被调用的函数
*
*/
	let throttle = function (func, wait) {
		let timeout = null,
			result = null,
			previous = 0; //=>上次执行时间点
		return function (...args) {
			let now = new Date,
				context = this;
//=>remaining小于等于0,表示上次执行至此所间隔时间已经超过一个时间间隔
			let remaining = wait - (now - previous);
			if (remaining <= 0) {
				clearTimeout(timeout);
				previous = now;
				timeout = null;
				result = func.apply(context, args);
			} else if (!timeout) {
				timeout = setTimeout(() => {
					previous = new Date;
					timeout = null;
					result = func.apply(context, args);
				}, remaining);
			}
			return result;
		};
	};

	let count = 0;

	function fn() {
		console.log(++count);
	}
	let lazyFn =throttle(fn, 1000);
	window.onscroll = lazyFn;
</script>
</body>
</html>
//1.使用:预览页面  打开控制台  滑动页面可看出效果