为什么要去了解函数节流和去抖呢?因为我想了解啊~搞事情~好了还是正经点吧,原因是是下面: 下面场景往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。
- window对象的resize、scroll事件
- 拖拽时的mousemove事件
- 射击游戏中的mousedown、keydown事件
- 文字输入、自动完成的keyup事件 实际上对于window的resize事件,实际需求大多为停止改变大小n毫秒后执行后续处理;而其他事件大多的需求是以一定的频率执行后续处理。针对这两种需求就出现了debounce和throttle两种解决办法。 那么我们就通过一个简单图片懒加载来了解下咯~
<html >
<head>
<title>通过懒加载了解节流和去抖</title>
</head>
<meta charset="utf-8">
<style>
img {
display: block;
width: 300px;
height: 200px;
float: left;
margin: 100px;
}
</style>
<body>
<img data-src="1.png" alt="1.png">
<img data-src="2.png" alt="2.png">
<img data-src="3.png" alt="3.png">
<img data-src="4.png" alt="4.png">
<img data-src="5.png" alt="5.png">
<img data-src="6.png" alt="6.png">
<img data-src="7.png" alt="7.png">
<img data-src="8.png" alt="8.png">
<img data-src="9.png" alt="1.png">
<img data-src="10.png" alt="1.png">
<img data-src="11.png" alt="1.png">
<img data-src="12.png" alt="1.png">
<img data-src="13.png" alt="1.png">
<img data-src="14.png" alt="1.png">
<img data-src="15.png" alt="1.png">
<img data-src="16.png" alt="1.png">
<img data-src="17.png" alt="1.png">
<img data-src="18.png" alt="1.png">
<img data-src="19.png" alt="1.png">
<img data-src="20.png" alt="1.png">
<img data-src="21.png" alt="1.png">
<img data-src="22.png" alt="1.png">
<img data-src="23.png" alt="1.png">
<img data-src="24.png" alt="1.png">
<img data-src="25.png" alt="1.png">
<img data-src="26.png" alt="1.png">
<img data-src="27.png" alt="1.png">
<img data-src="28.png" alt="1.png">
<img data-src="29.png" alt="1.png">
<script>
// 简单的去抖函数
// 去抖相比较节流函数要稍微简单一点,去抖是让函数延迟执行,而节流比去抖多了一个在一定时间内必须要执行一次
function debounce(fn, delay) {
// 持久化一个定时器 timer
let timer = null;
// 闭包函数可以访问 timer
return function() {
// 通过 'this' 和 'arguments'
// 获得函数的作用域和参数
let context = this;
let args = arguments;
// 如果事件被触发,清除 timer 并重新开始计时
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
}
}
// 简单的节流函数
// 好比一台自动的饮料机,按拿铁按钮,在出饮料的过程中,不管按多少这个按钮,都不会连续出饮料,中间按钮的响应会被忽略,必须要等这一杯的容量全部出完之后,再按拿铁按钮才会出下一杯。所以我们理解节流函数就是每隔一段时间执行一次函数。不用一动就执行,减少消耗。
function throttle(func, delay, time){
var timeout,
startTime = +Date.now();
return function(){
var context = this,
args = arguments,
curTime = +Date.now();
clearTimeout(timeout);
// 达到了最长触发时间
if(curTime - startTime >= time){
func.apply(context, args);
startTime = curTime;
}else{
// 没达到最长触发时间,重新设定定时器
timeout = setTimeout(function(){
func.apply(context, args);
}, delay);
}
}
}
//懒加载 图片 原理
var lazyLoadImg = function () {
//懒加载
var imgTags = document.querySelectorAll('img')
var n = 0
var len = imgTags.length
console.log(this)
for(var i = n ; i< len; i++){
var html_h = document.body.clientHeight
var html_scroll_t = document.body.scrollTop
if(imgTags[i].offsetTop < html_h + html_scroll_t){
if(imgTags[i].getAttribute('data-src')){
imgTags[i].src = imgTags[i].getAttribute('data-src')
imgTags[i].removeAttribute('data-src')
}
n++
}
}
}
lazyLoadImg()
//成功 this 是document 对象
document.addEventListener('scroll',throttle(lazyLoadImg, 500, 1000) , false)
//失败 this 是window 对象
document.addEventListener('scroll',function () {
throttle(lazyLoadImg, 500, 1000)()
}, false)
// var deepCopy1 = function (obj) {
// var _obj = {}
// _obj = JSON.parse(JSON.stringify(obj))
// return _obj
// }
//
// var deepCopy2 = function (obj) {
// var _obj = {}
// for( var k in obj) {
// if(typeof obj[k] === 'object'){
// _obj[k] = deepCopy2(obj[k])
// }else{
// _obj[k] = obj[k]
// }
// }
// return _obj
// }
var deepCopy3 = function (obj) {
var _obj = {}
obj = Object.entries(obj)
for( var [k,v] of obj) {
if(typeof v === 'object'){
_obj[k] = deepCopy2(v)
}else{
_obj[k] = v
}
}
return _obj
}
// Array.prototype.unique = function () {
// var _arr = []
// for(var i = 0; i <this.length;i ++) {
// if((_arr.indexOf(this[i]) === -1 )){
// _arr.push(this[i])
// }
// }
// return _arr
//
// }
// var Person = function (name) {
// this.name = name
// }
// Person.prototype.sayName = function () {
// console.log(this.name || 'default')
// }
// var new2 = function (func) {
// var o = Object.create(func.prototype);
// var k = func.call(o);
// if (typeof k === 'object') {
// return k;
// } else {
// return o;
// }
// };
// var new2 = function (fn,name) {
// var _o = Object.create(fn.prototype);
// var _obj = fn.call(_o,name)
//
// if(typeof _obj === 'object'){
// console.log('return _object')
// return _obj
// }else{
// console.log('return _o')
// return _o
// }
//
// }
// var p1 = new Person('bbb')
// p1.sayName()
//
// var p2 = new2(Person,'aaa')
// p2.sayName()
</script>
<!--<ul>-->
<!--<li><a href="#/">turn white</a></li>-->
<!--<li><a href="#/blue">turn blue</a></li>-->
<!--<li><a href="#/green">turn green</a></li>-->
<!--</ul>-->
</body>
</html>