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 html 调用 js方式 js判断undefined

aaaa ddddd ddddd ddddd 通过上述几种方法均可调用javascript角本。 相关知识: 1、在通过上述几种方法调用js脚本的时候,可以在js的函数中对相关内容进行验证...

百度地图API一:百度地图上循环显示标注点。使用闭包循环加载点击事件

本文记录:百度地图上循环显示标注点marker。使用立即执行函数和闭包循环加载点击事件,点击标注点显示信息窗口显示该标注点的具体信息。

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

百度地图API二:根据标注点坐标范围计算显示缩放级别zoom自适应显示地图

本文记录 如何通过标注点markers的坐标范围来计算百度地图的显示级别zoom。 百度地图每一个显示级别对应了一个比例尺,这里我们由比例尺入手。 计算最大经纬度与最小经纬度之间的距离,然后把这...

百度地图API三:实时轨迹动态展现

本文讲百度地图实时动态轨迹的实现。

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

javascript写函数的时候,常常遇到一个函数还没有运行完就再次调用同一个函数的情况,而这种情况下就可能发生一些未预期的结果。本文介绍javascript两种禁止一个函数没有运行结束时就再次调用的...

如何在页面上调用同一个方法

在日常生活中,我们根据客户的需求不得不改相应的代码,但是为了不改太多,采取简单,快捷的办法是我们程序员的重点。废话不多说,直接进入正题。 在jsp中,为了满足需求,我写了一个方法,调用两次。 由于...

理解fork()的一次调用两次执行

fork()函数是linux里多进程编程的基础,为linux成为强大的多用户操作系统提供了强有力的支持。 但是对于很多初学者而言,虽然知道怎么写多进程的程序,知道怎么fork()出一个子进程,却很少...

solr的下载、两种运行方式

我用的是solr-4.10.1版本。 下载: 从Solr官方网站(http://lucene.apache.org/solr/ )下载Solr4.10.3,根据Solr的运行环境,Linux下需要...

javascript调用函数的几种方法

function makeArray(arg1, arg2){ return [ this, arg1, arg2 ]; } 一次又一次的,我发现,那些有bug的Javascript代码是由于...

结束一个APP的几种方法

1. 在application中定义一个单例模式的Activity栈来管理所有Activity。并提供退出所有Activity的方法。 AndroidManifest.xml 添加权限 ...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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