• 防抖和节流的实现


    防抖

    • 触发函数后多长时间没再次触发,执行一次函数,如果再次触发重新开始计时
    • 常用于 key resize 等高频事件,输入框输入值时的本地缓存和异步请求
    // 当页面发生滚动的时1s后执行函数
    var timer = null;
    window.addEventListener('scroll', function() {
    	if(timer) clearTimeout(timer);
    	timer = setTimeout(function() {
    		console.log('我是a函数');
    	}, 1000)
    });
    
    // 把函数抽出来
    var timeout = null;
    function debounce() {
    	if(timeout) clearTimeout(timeout);
    	timeout = setTimeout(function() {
    		console.log('我是a函数');
    	}, 1000)
    }
    window.addEventListener('scroll', debounce);
    
    // 消除全局变量timeout
    function debounce(fn, delay) {
    	var timeout = null;
    	return function() {
    		if(timeout !== null) clearTimeout(timeout);
    		timeout = setTimeout(fn, delay);
    	}
    }
    function aa(){
        console.log('我是a函数')
    }
    window.addEventListener('scroll', debounce(aa, 1000));
    
    // 消除局部变量timeout
    function debounce(fun, delay) {
    	return function() {
    		let that = this;
    		clearTimeout(fun.id)
    		fun.id = setTimeout(function() {
    			fun.call(that)
    		}, delay)
    	}
    } 
    
    window.addEventListener('scroll', debounce(aa, 1000));
    
    // es6语法 减少局部变量
    function debounce(fun, delay) {
    	return function() {
    		clearTimeout(fun.id)
    		fun.id = setTimeout(() => {fun()}, delay)
    	}
    } 
    window.addEventListener('scroll', debounce(aa, 1000));
    
    • input输入触发事件的例子,增加参数传递
    //模拟一段ajax请求
    function ajax(content) {
      console.log('ajax request ' + content)
    }
    
    function debounce(fun, delay) {
        return function (args) {
            let that = this
            let _args = args
            clearTimeout(fun.id)
            fun.id = setTimeout(function () {
                fun.call(that, _args)
            }, delay)
        }
    }
        
    let inputb = document.getElementById('debounce')
    
    // 变量赋值
    let debounceAjax = debounce(ajax, 500)
    
    inputb.addEventListener('keyup', function (e) {
        debounceAjax(e.target.value)
    })
    
    

    节流

    • 规定多少时间内执行一次函数
    • 常用于click,scroll事件,监听是否滑动到底部加载更多
    • 节流实现的方式有两种时间戳和定时器
    // 1. 时间戳的方式  特点:第一次触发 立即执行
    var throttle = function(func, delay) {
    	var prev = Date.now();
    	return function() {
    		var that = this;
    		var args = arguments;
    		var now = Date.now();
    		if(now - prev >= delay) {
    			func.apply(that, args);
    			prev = Date.now();
    		}
    	}
    }
    
    function aa() {
    	console.log('我是aa函数');
    }
    window.addEventListener('scroll', throttle(aa, 1000));
    
    
    // 2. 定时器方式 特点:第一次不会立即执行,最后一次会延迟执行
    var throttle = function(func, delay) {
    	var timer = null;
    	return function() {
    		var that = this;
    		var args = arguments;
    		if(!timer) {
    			timer = setTimeout(function() {
    				func.apply(that, args);
    				timer = null;
    			}, delay);
    		}
    	}
    }
    
    function aa() {
    	console.log('我是aa函数');
    }
    window.addEventListener('scroll', throttle(aa, 1000));
    
    // 3. 时间戳+定时器  第一次会立即执行,最后一次会延迟执行
    var throttle = function(func, delay) {
    	var timer = null;
    	var startTime = Date.now();
    	return function() {
    		var curTime = Date.now();
    		var remaining = delay - (curTime - startTime);
    		var that = this;
    		var args = arguments;
    		clearTimeout(timer);
    		if(remaining <= 0) {
    			func.apply(that, args);
    			startTime = Date.now();
    		} else {
    			timer = setTimeout(func, remaining);
    		}
    	}
    }
    

    参考

    掘金-7分钟理解JS的节流、防抖及使用场景
    节流
    好理解

  • 相关阅读:
    Monad Maybe
    Linq怎么支持Monad
    创建我们第一个Monad
    Monad的重点
    解析器组合子
    NFA
    全排列算法
    R语言将数据框转成xts
    R语言的字符串处理
    wpf mvvm MenuItem的Command事件
  • 原文地址:https://www.cnblogs.com/bonly-ge/p/10102672.html
Copyright © 2020-2023  润新知