有人会介意解释下面这些脚本之间有什么区别吗?第一个是在Stack Overflow上找到的,第二个是我自己的版本,我更好理解但是没有用。为什么顺便说一下呢?
1
(function blink() {
$('.blinkMe').fadeOut(500).fadeIn(500, blink);
})();
2
function blink() {
$('.blinkMe').fadeOut(500).fadeIn(500, blink);
blink();
}
blink();
答案 0 :(得分:11)
第一个例子是立即调用的函数表达式(IIFE)。它是一个在创建后立即自行执行的功能。 IIFE是大多数流行的库(jQuery,Backbone.js,Modernizr等)使用的常见JavaScript设计模式,用于将所有库代码放在本地范围内。
在ES6中,如果您希望.blinkMe
只闪烁一次,可以使用Arrow function重写:
(() => $('.blinkMe').fadeOut(500).fadeIn(500))();
您可以根据需要链接尽可能多的fadeIn
和fadeOut
函数。如果你想让它无限循环,我建议采用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;
我不知道您要在页面上闪烁多少元素,如果它只是一个元素,您可以使用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()
内部的最大迭代次数进行测试。
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;
答案 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 docs,fadeIn()
有两个参数: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();