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

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


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

浅谈JavaScript如何运行中断或停止

在js运行过程中,在某些情况下想中断程序的运行,在网上查过,没有找到有这样的函数。一般情况下,大多数都是用return代替的。   因为js脚本很多都是基于函数的运行,return的作用是中断函数的...
  • qq_16559905
  • qq_16559905
  • 2016年04月08日 18:20
  • 14743

javascript 终止函数执行

1、如果终止一个函数的用return即可,实例如下: function testA(){     alert('a');     alert('b');     alert('c'); } ...
  • justflyhigh
  • justflyhigh
  • 2012年06月27日 10:59
  • 6349

js事件处理函数中return的作用

这里面的return含有一些细节知识: 例如:onClick='return add_onclick()'与 onClick='add_onclick()'的区别 JAVASCRIPT在事件中调用...
  • gchonghavefun
  • gchonghavefun
  • 2012年10月25日 20:56
  • 24256

js禁止方法频繁执行

我们在点击网页按钮时候,会连续点击,则对应的会频繁的请求后台的数据,如何避免这种操作。 用户会在某个时间内一直点,一秒内点了很多下,我们只执行最后一个操作就好了。 利用setTimeOut来实现,...
  • q646926099
  • q646926099
  • 2017年05月12日 22:54
  • 413

在JavaScript中想让一个函数执行完毕之后再执行下一个函数?

JavaScript中想让一个函数执行完毕之后再执行下一个函数
  • qq_23067521
  • qq_23067521
  • 2017年06月19日 09:03
  • 5131

js 执行完一个函数之后再执行另外一个函数

一、第一种情况:运动函数执行完之后再执行另外一个函数 注释:按钮点击之后,div先显示出来,然后宽度和高度再增加到300px button class="btn">点击我button> div...
  • vivian_wang07
  • vivian_wang07
  • 2017年05月17日 19:04
  • 2949

如何终止JS继续运行??

终止JS运行有如下几种可能: 终止函数的运行的方式有两种 在函数中使用return,则当遇到return时,函数终止执行,控制权继续向下运行 在函数中使用try-catch异...
  • wkj001
  • wkj001
  • 2016年12月19日 23:19
  • 2390

Linux启动为什么没有最先调用main函数?

学过C语言的人都知道,用C语言设计的程序都有一个main函数,而且是从main函数开始执行的。Linux 0.11的代码是用C语言编写的。奇怪的是,为什么在操作系统启动时先执行的是三个由汇编语言写成的...
  • cmdssd1
  • cmdssd1
  • 2014年09月27日 17:39
  • 1924

js停止setInterval函数的运行

在某些情况下,我们需要用到setInterval函数,让某方法在每隔固定时间段后自动执行。 可满足某些条件后我们需要将其终止,不再运行,做法如下: Auto=window.setInterval(...
  • woai671
  • woai671
  • 2015年06月01日 17:25
  • 2222

js实现每次调用一个函数自动加1

1.首先考虑使用闭包   function getId () {   'use strict';      var i = 0;   getId = function () {     r...
  • L18230301852
  • L18230301852
  • 2017年10月15日 16:16
  • 757
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript两种禁止一个函数没有运行结束时就再次调用的方法
举报原因:
原因补充:

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