循环JavaScript函数

div*_*r11 6 javascript jquery

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

1.

(function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
})();
Run Code Online (Sandbox Code Playgroud)

2.

function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
  blink();
}
blink();
Run Code Online (Sandbox Code Playgroud)

Pat*_*607 11

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

在ES6中,如果您想要只闪烁一次,可以使用箭头功能重写.blinkMe:

(() => $('.blinkMe').fadeOut(500).fadeIn(500))();
Run Code Online (Sandbox Code Playgroud)

你可以连续使用尽可能多的fadeInfadeOut功能,只要你想,当然.如果你想让它无限循环我会建议IIFE方式.

有关IIFE更多信息在这里.


关于你的第二个例子.你在自己的函数中调用函数(也称为递归循环).在你的情况下,这会创建一个无限循环,这就是为什么它不起作用.删除blink();函数内部它将工作:

function blink() { 
    $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
}
blink();
Run Code Online (Sandbox Code Playgroud)

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

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

// Arrow function:
//(() => document.getElementsByClassName('blinkMe')[0].className += ' blinkActive')();
Run Code Online (Sandbox Code Playgroud)
.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; }
}
Run Code Online (Sandbox Code Playgroud)
<div class="blinkMe"></div>
Run Code Online (Sandbox Code Playgroud)

我不知道你想在页面上闪烁多少个元素,如果它只是一个元素,你可以使用id而不是类.请记住,@keyframesIE9或更早版本以及Opera Mini:Link不支持该规则.

  • 您的第一个代码段不起作用 - blink未定义. (4认同)
  • @MasterDJon不,从不调用回调,因为JS线程处于永不产生的无限循环中. (2认同)

Nei*_*l S 7

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

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


Mas*_*Jon 6

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

编辑:但正如我刚才所了解的那样,计时器不会在JavaScript中的其他线程上执行.因此,blink()在内部blink功能通吃的执行框架和blink回调永远不会被调用,但它仍然是注册到被调用.因为,我通过添加blink()可以调用内部的最大迭代次数来测试.

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


Ale*_*ara 6

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

(function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
})();
Run Code Online (Sandbox Code Playgroud)


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

function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
  blink();
}
blink();
Run Code Online (Sandbox Code Playgroud)

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

function blink() { 
  $('.blinkMe').fadeOut(500).fadeIn(500, blink); 
}
blink();
Run Code Online (Sandbox Code Playgroud)