Skip to content

Latest commit

 

History

History
235 lines (203 loc) · 6.89 KB

js-throttle.md

File metadata and controls

235 lines (203 loc) · 6.89 KB

通过简单的懒加载了解节流和去抖

背景

为什么要去了解函数节流和去抖呢?因为我想了解啊~搞事情~好了还是正经点吧,原因是是下面: 下面场景往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。

  1. window对象的resize、scroll事件
  2. 拖拽时的mousemove事件
  3. 射击游戏中的mousedown、keydown事件
  4. 文字输入、自动完成的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>