循环JavaScript函数

时间:2016-05-13 23:22:32

标签: javascript jquery

有人会介意解释下面这些脚本之间有什么区别吗?第一个是在Stack Overflow上找到的,第二个是我自己的版本,我更好理解但是没有用。为什么顺便说一下呢?

1

(function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
})();

2

function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
  blink();
}
blink();

6 个答案:

答案 0 :(得分:11)

第一个例子是立即调用的函数表达式IIFE)。它是一个在创建后立即自行执行的功能。 IIFE是大多数流行的库(jQuery,Backbone.js,Modernizr等)使用的常见JavaScript设计模式,用于将所有库代码放在本地范围内。

在ES6中,如果您希望.blinkMe只闪烁一次,可以使用Arrow function重写:

(() => $('.blinkMe').fadeOut(500).fadeIn(500))();

您可以根据需要链接尽可能多的fadeInfadeOut函数。如果你想让它无限循环,我建议采用IIFE方式。

有关IIFE here的更多信息。

关于你的第二个例子。您在自己的函数中调用函数(也称为递归循环)。在你的情况下,这会产生一个无限循环,这就是它无法工作的原因。删除函数内的blink();,它将起作用:

function blink() { 
    $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
}
blink();

除了使用javascript,您还可以使用CCS3动画解决此问题。 CSS3动画在一个单独的线程中运行。这是一个没有jQuery的解决方案:



(function blink() {
  document.getElementsByClassName('blinkMe')[0].className += ' blinkActive';
})();

// Arrow function:
//(() => document.getElementsByClassName('blinkMe')[0].className += ' blinkActive')();

.blinkMe {
  width: 80px;
  height: 80px;
  background: deepskyblue;
}
.blinkActive {
  -webkit-animation: blink 1s infinite;
  animation: blink 1s infinite;
}
@-webkit-keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

<div class="blinkMe"></div>
&#13;
&#13;
&#13;

我不知道您要在页面上闪烁多少元素,如果它只是一个元素,您可以使用ID而不是类。请注意,IE9或更早版本以及Opera Mini不支持@keyframes规则:Link

答案 1 :(得分:7)

第一个是IIFE。也就是说,在声明函数之后立即调用(执行)该函数。它没有附加到全局窗口对象,因此不会污染它。

第二个函数是指数递归的。每次运行时,它都会自动调用两次,一次调用fadeIn jquery方法,再一次调用函数体。

答案 2 :(得分:6)

$('.blinkMe').fadeOut(500).fadeIn(500, blink);在结束时已调用blink。所以回调blink()就像调用两次函数(每次调用甚至更多)。所以这个电话就是问题。

编辑:但正如我刚才所了解的那样,计时器并未在JavaScript中的其他线程上执行。因此,blink()函数中的blink接受所有执行帧,并且永远不会调用blink回调,但它仍然被注册为被调用。因为,我通过添加可以调用blink()内部的最大迭代次数进行测试。

&#13;
&#13;
function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
  //blink();
}
blink();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="blinkMe">Blinking</span>
&#13;
&#13;
&#13;

答案 3 :(得分:6)

在此片段中,创建一个命名函数,然后在Immediately-Invoked Function Expression中立即执行一次。函数名只能用于自身,因此可以在函数体的闭包中再次调用它,在这种情况下作为fadeIn函数的回调。

(function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
})();


在此片段中,创建并调用命名函数。此外,该函数再次调用自身,这将创建无限递归,这就是失败的原因。与上一个代码段不同,blink也可以在函数闭包本身之外使用。

function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
  blink();
}
blink();

除非blink()范围不同,否则删除函数内部的blink调用将使其功能几乎相同。

function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
}
blink();

答案 4 :(得分:2)

这是一个递归函数(动画)。

根据jQuery docsfadeIn()有两个参数:duration(以毫秒为单位)和complete。第二个参数是动画完成后调用的函数。它本身或其他功能。

在第二个函数中,你一次又一次地调用blink() ......但第二个和第三个函数从未到来。最好的方法是第一种。

答案 5 :(得分:2)

您的功能有效,但导航器因递归过多而阻止它。因为你在fadeIn之后正在调用blink() 试试吧,

function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
  //remove this call which causes too many recursions 
  //blink();
 }
//then call the method
 blink();