javascript两种禁止一个函数没有运行结束时就再次调用的方法(解决抖动的问题)...

请注意,本文转载。原地址:http://blog.csdn.net/liusaint1992/article/details/49933971

 

JavaScript写函数的时候,常常遇到一个函数还没有运行完就再次调用同一个函数的情况,而这种情况下就可能发生一些未预期的结果。

 

之前在javascript论坛上回答过一个问题,JS中图片抖动问题 

它这个图片,mouseover时间会让它抖动一阵子,然后回到原来的位置,但是如果在它还没有抖动结束的时候,再去触发mouseover的时候,就会在原来的函数还没有执行完恢复到原地的时候再次执行,从而导致最终图片偏离原位。

 
问题代码:
 
<!doctype html>  
<html>  
<head>  
    <meta charset="utf-8">  
    <title></title>  
    <style type="text/css">  
        img{width:150px; height:150px; position:absolute; top:50px; left:300px; }   
    </style>  
    <script>  
        window.onload = function(){  
            function getStyle(obj,attr){  
                return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];  
            }  
            function shake(obj,attr,endFn){  
                var arr = [];  
                for(var i=20;i>0;i-=2){  
                    arr.push(i,-i);  
                }  
                arr.push(0);  
                var num = 0;  
                var origin = parseInt(getStyle(obj,attr));  
                obj.shake = setInterval(function(){  
                    obj.style[attr] = origin + arr[num] + 'px';  
                    num++;  
                    if(num == arr.length){  
                        clearInterval(obj.shake);  
                        endFn && endFn();  
                    }  
                },50)  
            }  
            var img = document.getElementsByTagName("img")[0];  
            img.onmouseover = function(){  
                shake(this,'top');  
            }  
        }  
    </script>  
</head>  
<body>  
    <img src="http://avatar.csdn.net/2/9/2/3_liusaint1992.jpg">  
</body>  
</html>  

 

 
只要保证一次函数没有执行结束之前不再次执行该函数就可以了。 这里给出两种方法。
 
方法一,用全局变量标识函数执行状态。
 
使用一个全局变量做标识,shaking = false。 我们执行函数之前先判断  if(shaking == false){return;}shaking = true  ,  然后在函数执行结束的时候加一句:shaking = false。标识函数没有在执行。
 
具体代码:
<!doctype html>  
<html>  
<head>  
    <meta charset="utf-8">  
    <title></title>  
    <style type="text/css">  
        img{width:150px; height:150px; position:absolute; top:50px; left:300px; }
    </style>  
    <script>  
       window.onload = function(){  
        function getStyle(obj,attr){  
            return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];  
        }  
        var shaking = false;  
        function shake(obj,attr,endFn){  
            if(shaking == true){  
                return;  
            }  
            shaking = true;  
            var arr = [];  
            for(var i=20;i>0;i-=2){  
                arr.push(i,-i);  
            }  
            arr.push(0);  
            var num = 0;  
            var origin = parseInt(getStyle(obj,attr));  
            obj.shake = setInterval(function(){  
                obj.style[attr] = origin + arr[num] + 'px';  
                num++;  
                if(num == arr.length){  
                    clearInterval(obj.shake);  
                    endFn && endFn();  
                    shaking = false;  
                }  
            },50)  
            
        }  
        var img = document.getElementsByTagName("img")[0];  
        img.onmouseover = function(){  
            shake(this,'top');  
        }  
    </script>  
</head>  
<body>  
    <img src="http://avatar.csdn.net/2/9/2/3_liusaint1992.jpg">  
</body>  
</html>  

 



可是这样毕竟引了了一个新的全局变量,不到迫不得已的时候,我是不想引用新的全局变量的。 那么有没有不用全局变量的方法来阻止函数没执行结束的时候就再次被执行呢?最近写一个控件的时候,突然想到一种新的方法。 用起来也比较溜。
 
 
方法二:用销毁函数然后再恢复函数的方法阻止函数运行。  
原理是,如果我们在执行这个函数的时候,把这个函数销毁了,函数执行结束的时候再将这个函数恢复。   在函数执行过程中,这个函数名都不存在了,自然无法调用。   一执行该函数,就给该函数做一个备份,然后销毁该函数,函数主体执行结束用备份的函数恢复我们销毁的函数。
 
示例代码:
[javascript]  view plain  copy
 
        function a(){  
            var b = a;//备份  
            a = null;//销毁  
            console.log('i am in a ');  
            a = b;//恢复  
        }  
    </script>  

 


运用到上面的案例中:
 
关键代码:
 
// var shaking = false;  
function shake(obj,attr,endFn){  
    // if(shaking == true){  
    //     return;  
    // }  
    // shaking = true;  
    var backup = shake;//备份  
    shake = null;//销毁  
    var arr = [];  
    for(var i=20;i>0;i-=2){  
        arr.push(i,-i);  
    } 
    arr.push(0);  
    var num = 0;  
    var origin = parseInt(getStyle(obj,attr));  
    obj.shake = setInterval(function(){  
        obj.style[attr] = origin + arr[num] + 'px';  
        num++;  
        if(num == arr.length){  
           clearInterval(obj.shake);  
           endFn && endFn();  
            // shaking = false;  
            shake = backup;//抖动结束之后恢复  
        }  
    },50)
}

 


经测试,两种方法实现了同样的效果!
 
 

转载于:https://www.cnblogs.com/windyet/articles/6671328.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值