javascript两种禁止一个函数没有运行结束时就再次调用的方法

原创 2015年11月19日 22:08:13

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。标识函数没有在执行。

具体代码:

                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');
			}
		}


可是这样毕竟引了了一个新的全局变量,不到迫不得已的时候,我是不想引用新的全局变量的。 那么有没有不用全局变量的方法来阻止函数没执行结束的时候就再次被执行呢?最近写一个控件的时候,突然想到一种新的方法。 用起来也比较溜。


方法二:用销毁函数然后再恢复函数的方法阻止函数运行。  
原理是,如果我们在执行这个函数的时候,把这个函数销毁了,函数执行结束的时候再将这个函数恢复。   在函数执行过程中,这个函数名都不存在了,自然无法调用。   一执行该函数,就给该函数做一个备份,然后销毁该函数,函数主体执行结束用备份的函数恢复我们销毁的函数。

示例代码:
       function a(){
            var b = a;//备份
            a = null;//销毁
            console.log('i am in a ');
            a = b;//恢复
        }

运用到上面的案例中:

关键代码:
     // 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)
 
    }

经测试,两种方法实现了同样的效果!
不知道还没有其他更好的方法可以实现同样的效果,甚至有更高的效率。 欢迎留言交流。


版权声明:本文为博主原创文章,转载请注明出处。

相关文章推荐

js禁止方法频繁执行

我们在点击网页按钮时候,会连续点击,则对应的会频繁的请求后台的数据,如何避免这种操作。 用户会在某个时间内一直点,一秒内点了很多下,我们只执行最后一个操作就好了。 利用setTimeOut...

JS中终止函数执行的代码

1.假如终止一个函数用return即可:例 function testA(){ alert("a"); alert('b'); alert('c'); } testA(); 函数执行会...

javascript 终止函数执行

1、如果终止一个函数的用return即可,实例如下: function testA(){     alert('a');     alert('b');     alert('c'); } ...

C++面试题: main函数执行完之后还会调用其他的函数吗?

我们通常认为C语言的起始函数是main()函数,实质上一个程序的启动函数并不一定是main()函数,这个可以采用链接器来设置,但是gcc中默认main()就是C语言的入口函数,在main函数启动之前,...

两种防止js重复执行的方法

其一: function test(){ console.log(0); } function throttle(fun){ if(fun...

h5 plus实现照片上传功能

该功能实现主要用到h5 plus 的gallery和uploader两个接口,gallery调用手机相册选取照片,uploader用来上传选择的图片到服务器。本人开始研究h5刚十几天,不足之处,希望各...

oracle按开始时间和结束时间进行数据拆分的自定义函数

oracle按开始时间和结束时间进行数据拆分的自定义函数 故事背景:前段时间做数据报表时,遇到统计每个月的的住院人次(注意是“人次”,不是“人数”)怎么办呢,查询了资料(度娘),只发现了“兔子”...

ServletContextListener 使用。web启动监听启动和结束时的调用

web.xml监听配置 org.springframework.web.context.request.RequestContextListener XXXX.C...
  • jspamd
  • jspamd
  • 2016年04月13日 16:09
  • 952

玩《变形金刚》到第一关结束时总是出现0xffffffff引用的xffffffff内存不能为read

内存不能为read/written 问题的简单解决办法:(原创答案,欢迎分享→请活学活用→仅供参考): 一、硬件的可能性是比较小的,如果是硬件,那就应该是内存条跟主机不兼容的问题导致的 如果能排除硬件...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript两种禁止一个函数没有运行结束时就再次调用的方法
举报原因:
原因补充:

(最多只允许输入30个字)