• 理解闭包的使用方法


    以前对闭包的理解比较浅,只知道一个函数里面返回另一个匿名函数就是闭包,具体怎么用一直是模模糊糊的,最近为了解决一个防止重复点击的问题,查了不少的资料,现在应该是比较清楚闭包的用法了。来代码说话吧。

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>测试函数节流</title>
        <style>
            #container{
                width: 100%;
                height: 200px;
                border: 1px solid #646464;
                color: #000000;
            }
        </style>
    
    </head>
    <body >
    <div id="container"></div>
    </body>
    
    <script>

      function alertSomething(){
        alert("您的鼠标正在移动");
      };
      document.getElementById("container").onmousemove = alertSomething;


    </script>
    </html>

    现在鼠标在页面上的那块区域一移动就会触发一个函数,只要我不停止函数就一直会触发,但是我们想要,在多次移动只触发一次函数,这样能解决我们的调用的次数。这时代码应该是这个样子的。

    var timer;
    
    function throttle(){
    
              clearTimeout(timer);
              timer = setTimeout(function(){
                    alertSomething()
    
                },1000);
    
    
        }

    代码看上去没什么问题,对吧!但是当你的页面已经有很多逻辑的时候,这里就不太好用了,比如说这样

    var obj = null;
    var timer= null;
    var strBtn = null;
    var youka = null;
    
    function shake(e, oncomplete, distance, time){
    
            if(typeof e === 'string'){
                e = document.getElementById(e);
            }
    
            if(!time){
                time = 500;
            }
    
            if(!distance){
                distance = 5;
            }
    
            var originalStyle = e.style.cssText;
            e.style.position = 'relative';
    
            var start = (new Date()).getTime();
            animate();
    
            function animate(){
    
                var now = (new Date()).getTime();
                var elapsed = now - start;
                var fraction = elapsed / time;
    
                if(fraction < 1){
                    var x = distance * Math.sin(fraction * 4 * Math.PI);
                    e.style.left = x + 'px';
    
                    setTimeout(animate, Math.min(25, time - elapsed));
                }else{
                    e.style.cssText = originalStyle
    
                    if(oncomplete){
                        oncomplete(e);
                    }
                }
            }
        }
    
    function shake(e, oncomplete, distance, time){
    
            if(typeof e === 'string'){
                e = document.getElementById(e);
            }
    
            if(!time){
                time = 500;
            }
    
            if(!distance){
                distance = 5;
            }
    
            var originalStyle = e.style.cssText;
            e.style.position = 'relative';
    
            var start = (new Date()).getTime();
            animate();
    
            function animate(){
    
                var now = (new Date()).getTime();
                var elapsed = now - start;
                var fraction = elapsed / time;
    
                if(fraction < 1){
                    var x = distance * Math.sin(fraction * 4 * Math.PI);
                    e.style.left = x + 'px';
    
                    setTimeout(animate, Math.min(25, time - elapsed));
                }else{
                    e.style.cssText = originalStyle
    
                    if(oncomplete){
                        oncomplete(e);
                    }
                }
            }
        }
    
    function shake(e, oncomplete, distance, time){
    
            if(typeof e === 'string'){
                e = document.getElementById(e);
            }
    
            if(!time){
                time = 500;
            }
    
            if(!distance){
                distance = 5;
            }
    
            var originalStyle = e.style.cssText;
            e.style.position = 'relative';
    
            var start = (new Date()).getTime();
            animate();
    
            function animate(){
    
                var now = (new Date()).getTime();
                var elapsed = now - start;
                var fraction = elapsed / time;
    
                if(fraction < 1){
                    var x = distance * Math.sin(fraction * 4 * Math.PI);
                    e.style.left = x + 'px';
    
                    setTimeout(animate, Math.min(25, time - elapsed));
                }else{
                    e.style.cssText = originalStyle
    
                    if(oncomplete){
                        oncomplete(e);
                    }
                }
            }
        }
    
    function shake(e, oncomplete, distance, time){
    
            if(typeof e === 'string'){
                e = document.getElementById(e);
            }
    
            if(!time){
                time = 500;
            }
    
            if(!distance){
                distance = 5;
            }
    
            var originalStyle = e.style.cssText;
            e.style.position = 'relative';
    
            var start = (new Date()).getTime();
            animate();
    
            function animate(){
    
                var now = (new Date()).getTime();
                var elapsed = now - start;
                var fraction = elapsed / time;
    
                if(fraction < 1){
                    var x = distance * Math.sin(fraction * 4 * Math.PI);
                    e.style.left = x + 'px';
    
                    setTimeout(animate, Math.min(25, time - elapsed));
                }else{
                    e.style.cssText = originalStyle
    
                    if(oncomplete){
                        oncomplete(e);
                    }
                }
            }
        }
    
    function shake(e, oncomplete, distance, time){
    
            if(typeof e === 'string'){
                e = document.getElementById(e);
            }
    
            if(!time){
                time = 500;
            }
    
            if(!distance){
                distance = 5;
            }
    
            var originalStyle = e.style.cssText;
            e.style.position = 'relative';
    
            var start = (new Date()).getTime();
            animate();
    
            function animate(){
    
                var now = (new Date()).getTime();
                var elapsed = now - start;
                var fraction = elapsed / time;
    
                if(fraction < 1){
                    var x = distance * Math.sin(fraction * 4 * Math.PI);
                    e.style.left = x + 'px';
    
                    setTimeout(animate, Math.min(25, time - elapsed));
                }else{
                    e.style.cssText = originalStyle
    
                    if(oncomplete){
                        oncomplete(e);
                    }
                }
            }
        }
    
    function shake(e, oncomplete, distance, time){
    
            if(typeof e === 'string'){
                e = document.getElementById(e);
            }
    
            if(!time){
                time = 500;
            }
    
            if(!distance){
                distance = 5;
            }
    
            var originalStyle = e.style.cssText;
            e.style.position = 'relative';
    
            var start = (new Date()).getTime();
            animate();
    
            function animate(){
    
                var now = (new Date()).getTime();
                var elapsed = now - start;
                var fraction = elapsed / time;
    
                if(fraction < 1){
                    var x = distance * Math.sin(fraction * 4 * Math.PI);
                    e.style.left = x + 'px';
    
                    setTimeout(animate, Math.min(25, time - elapsed));
                }else{
                    e.style.cssText = originalStyle
    
                    if(oncomplete){
                        oncomplete(e);
                    }
                }
            }
        }

    当然把timer设为全局是没有问题的,但是如果你的业务逻辑很复杂,代码结构很乱,对于以后的维护就会变得很困难了。所以为了以后你维护代码或者维护你代码的人,为了自己为了别人,所以我我们把方法改进了,变成这样

    function throttle(func){
            var timer;
            return function(){
                var context = this;
                var args = arguments;
              clearTimeout(timer);
              timer = setTimeout(function(){
                    func.apply(context,args);
    
                },1000);
            }
    
        }

    这样变量不会被污染,且后面维护代码的人也变得简单轻松多了,别人一看看不懂,他就会惊叹哇大神啊,然后叫你帮忙看一下,这个既装逼又提高技术的做法,何乐而不为呢?

    这段代码的意思就是,设置一个定时器,当上一次函数没有完成时,先清除掉,再调用。

  • 相关阅读:
    win10打开相机提示我们找不到你的相机
    Potplay视频播放画面扭曲
    SIFT特征匹配算法介绍
    SelectiveSearchCodeIJCV遇到First two input arguments should have the same 2D dimension
    mybatis逆向工程mvn插件
    ssm配置
    springmvc配置
    MyBatis如何禁用掉一级缓存
    Mybatis中#{}和${}的区别
    Java demo之IO
  • 原文地址:https://www.cnblogs.com/masita/p/5335896.html
Copyright © 2020-2023  润新知