如何强制javascript函数同步/顺序执行?
我正在创建一个实用方法,它可以帮助使用jQuery按顺序淡入元素。正如您在下面的代码中所看到的,我添加了一个额外的类作为如何强制javascript函数同步/顺序执行?,javascript,jquery,html,asynchronous,Javascript,Jquery,Html,Asynchronous,我正在创建一个实用方法,它可以帮助使用jQuery按顺序淡入元素。正如您在下面的代码中所看到的,我添加了一个额外的类作为alreadyFadedIna标志。在方法调用SequentialyFadein(…)结束时,我想执行cleanUp,其中我想删除在SequentialyFadein(…)方法内所选元素中添加的标志类 <html> <head> <script src="http://code.jquery.com/jquery-latest.js"><
alreadyFadedIn
a标志。在方法调用SequentialyFadein(…)
结束时,我想执行cleanUp
,其中我想删除在SequentialyFadein(…)
方法内所选元素中添加的标志类
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {
function sequentialFadeIn(selectorText, speed, display, callBack) {
display = typeof display !== 'undefined' ? display : "block";
function helper() {
nextElementToFadeIn = $(selectorText).not(".alreadyFadedIn").first();
nextElementToFadeIn.fadeIn(speed, function() {
$(this).addClass("alreadyFadedIn");
helper();
}).css("display", display);
}
helper();
callBack(selectorText);
}
sequentialFadeIn(".toBeFaddedIn", "slow", "inline-block",function cleanUp(selectorText1){
$(selectorText1).removeClass("alreadyFadedIn");
console.log("Clean up has been performed.");
console.log("Selector Text: " +selectorText1);
} );
});
</script>
</head>
<body><style media="screen" type="text/css">
.hello {
background-color: blue;
height:50px;
width: 50px;
display: none;
}
</style>
<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>
</body></html>
$(文档).ready(函数(){
功能顺序FADEIN(选择文本、速度、显示、回调){
显示=显示类型!=“未定义”?显示:“块”;
函数助手(){
nextElementToFadeIn=$(selectorText).not(“.alreadyFadeIn”).first();
nextElementToFadeIn.fadeIn(速度,函数(){
$(this.addClass(“alreadyFadedIn”);
助手();
}).css(“显示”,显示);
}
助手();
回调(selectorText);
}
顺序FADEIN(“.toBeFaddedIn”、“慢速”、“内联块”、函数清理(selectorText1){
$(selectorText1.removeClass(“alreadyFadedIn”);
日志(“已执行清理”);
日志(“选择器文本:+selectorText1”);
} );
});
.你好{
背景颜色:蓝色;
高度:50px;
宽度:50px;
显示:无;
}
查看inspect元素时,我注意到类alreadyFadedIn
没有被删除。在我看来,原因是cleanUp方法与sequentiallyFadeIn
方法的主逻辑异步执行,该方法位于helper()
中。您还可以注意到日志消息“cleanup has performed.”甚至在div完成淡入之前就打印出来了
在sequentialyfadedin
方法中的主逻辑完成后,如何执行cleanUp
调用?有什么建议吗
jsiddle上的代码:您需要检查是否有任何元素仍然需要淡入。如果没有元素保留,则调用清理回调。下面是我如何实现它的:
if ($(selectorText).is(":not(.alreadyFadedIn)")) {
//Your main logic
nextElementToFadeIn = $(selectorText).not(".alreadyFadedIn").first();
nextElementToFadeIn.fadeIn(speed, function() {
$(this).addClass("alreadyFadedIn");
helper();
}).css("display", display);
} else {
//No elements remain, cleanup time
callBack(selectorText);
}
在外部条件中,我检查是否至少有一个元素没有淡入,否则调用回调
演示:您需要检查是否还有任何元素需要淡入。如果没有元素保留,则调用清理回调。下面是我如何实现它的:
if ($(selectorText).is(":not(.alreadyFadedIn)")) {
//Your main logic
nextElementToFadeIn = $(selectorText).not(".alreadyFadedIn").first();
nextElementToFadeIn.fadeIn(speed, function() {
$(this).addClass("alreadyFadedIn");
helper();
}).css("display", display);
} else {
//No elements remain, cleanup time
callBack(selectorText);
}
在外部条件中,我检查是否至少有一个元素没有淡入,否则调用回调
演示:如果您只需像这样重写代码,就更容易、更干净、更快了
$(document).ready(function() {
function sequentialFadeIn(selectorText, speed, display, callBack) {
display = display || "block";
var els = $(selectorText),
i = 0;
(function helper() {
els.eq(i++).fadeIn(speed, helper).css("display", display);
if (callback && i === els.length)
callback(selectorText); // Not really needed any more
})();
}
sequentialFadeIn(".toBeFaddedIn", "slow", "inline-block", function cleanUp(selectorText1){
// not really needed any more
// $(selectorText1).removeClass("alreadyFadedIn");
});
});
演示:
您所做的DOM选择比需要的多得多。如果您只需像这样重写代码,就会更容易、更干净、更快
$(document).ready(function() {
function sequentialFadeIn(selectorText, speed, display, callBack) {
display = display || "block";
var els = $(selectorText),
i = 0;
(function helper() {
els.eq(i++).fadeIn(speed, helper).css("display", display);
if (callback && i === els.length)
callback(selectorText); // Not really needed any more
})();
}
sequentialFadeIn(".toBeFaddedIn", "slow", "inline-block", function cleanUp(selectorText1){
// not really needed any more
// $(selectorText1).removeClass("alreadyFadedIn");
});
});
演示:
您所做的DOM选择远远超出了需要。要扩展我的评论,这里有一个简化版本,不使用其他类:
function fadeThenNext(element){
element.fadeIn("fast", function() {
element=element.next(".toBeFaddedIn");
if (element.length) fadeThenNext(element);
});
}
fadeThenNext($(".toBeFaddedIn").first());
演示:
[更新]如果元素不是兄弟元素,则为更通用的版本:
function fadeSequence(elements){
elements.first().fadeIn("fast", function() {
fadeSequence(elements.slice(1));
});
}
fadeSequence($(".toBeFaddedIn"));
fiddle:要扩展我的评论,这里有一个简化版本,不使用其他类:
function fadeThenNext(element){
element.fadeIn("fast", function() {
element=element.next(".toBeFaddedIn");
if (element.length) fadeThenNext(element);
});
}
fadeThenNext($(".toBeFaddedIn").first());
演示:
[更新]如果元素不是兄弟元素,则为更通用的版本:
function fadeSequence(elements){
elements.first().fadeIn("fast", function() {
fadeSequence(elements.slice(1));
});
}
fadeSequence($(".toBeFaddedIn"));
fiddle:看起来您必须在
helper
函数中运行回调,一旦nextElementToFadeIn
不再包含任何元素。您需要在fadeIn
的完成函数中调用回调
函数。您的代码执行helper
(这将删除类alreadyFadedIn
)立即,添加类alreadyFadedIn
的匿名函数将在fadeIn动画完成后执行。这似乎是错误的。但您有修复逻辑的成分。您可以立即或在动画结束时执行代码。这看起来过于复杂。为什么不使用next()进行链淡入,而无需添加类?@FelixKling您的解决方案成功了!:)以下是JSFIDLE上更新的代码:看起来您必须在helper
函数中运行回调,直到nextElementToFadeIn
不再包含任何元素。您需要在fadeIn
的完成函数中调用callback
函数。您的代码执行helper
(这将删除类alreadyFadedIn
)立即,添加类alreadyFadedIn
的匿名函数将在fadeIn动画完成后执行。这似乎是错误的。但您有修复逻辑的成分。您可以立即或在动画结束时执行代码。这看起来过于复杂。为什么不使用next()进行链淡入,而不需要添加类?@FelixKling您的解决方案成功了!:)以下是关于jsfiddle的更新代码:我还根据@FelixKing在问题注释中的建议提出了类似的建议。演示:我还根据@FelixKing在问题评论中的建议提出了类似的建议。演示:啊!漂亮:)当我们有.eq()
作为活套时,谁需要额外的标志呢!谢谢你指出这条路。啊!漂亮:)当我们有.eq()
作为活套时,谁需要额外的标志呢!感谢您指出这种方式。它要求所选元素彼此是兄弟元素,有时可能并非如此。但适用于某些需要应用此效果的场景,比如在元素列表上。对,对于更通用的代码,您需要遍历选择器,如@user1689607的示例所示。关键是你不需要额外的课程!它要求所选元素彼此是兄弟元素,有时可能并非如此。