问题
I'm new to jQuery and stack overflow, so I'll try to be specific, but please bear with me. I'm trying to create a text slider with associated links from scratch, using modulus to iterate through the list and repeat.
Here's the code I'm working with:
ul#text { position: relative; margin-bottom: 40px; height: 40px; }
ul#text li { position: absolute; display: none; }
.active { font-weight: bold; }
<ul id="text">
<li id="textBody">Suffering is not a result of physical pain alone. It can be compounded by changes in one's life, and changes in the self. <em>We understand, and we can help.</em></li>
<li id="textFamily">Aggressive assessment of physical symptoms & pain in the body are key to support <em>the best possible quality of life</em>.</li>
<li id="textFunction">Chronic pain & illness may affect your role in your family. We work with you and your family as you confront those changes.</li>
<li id="textPsyche">Chronic pain and illness make even everyday activities challenging. We will help you maintain independence and physical function.</li>
<li id="textSuffering">Changes in the physical body mean changes in the self. We will provide support as you navigate those changes in the psyche.</li>
</ul>
<ul id="vivid_buttons">
<li><a href="#" id="buttonBody">BODY</a></li>
<li><a href="#" id="buttonFamily" class="active">FAMILY</a></li>
<li><a href="#" id="buttonFunction">FUNCTION</a></li>
<li><a href="#" id="buttonPsyche">PSYCHE</a></li>
<li><a href="#" id="buttonSuffering">SUFFERING</a></li>
</ul>
$(document).ready(function () {
function fadeAndMove() {
var nextLi = $("#text > li:nth-child(" + i % 5 + ")");
var nextA = $("#vivid_buttons > li:nth-child(" + i % 5 + ") > a");
nextLi.fadeIn(1000, function () {
$("#vivid_buttons > li > a").removeClass("active");
nextA.addClass("active");
setTimeout(function () {
nextLi.fadeOut(1000);
}, 4000);
});
}
for (i = 1; i < 7; i++) {
fadeAndMove($("#text"));
}
});
In simple language, I want to fade in a sentence from the first list, and highlight the corresponding link on the bottom list. I then want it to fade out and move to the next item.
I thought I could use modulus (%) and a for loop to iterate through and create an infinite loop, but when I put this in it's like it executes everything all at once, not iterating through (fading in and out) for each item.
I know this is confusing, but I'd appreciate any help I could get.
回答1:
Get rid of the for
loop, and just have the setTimeout call the fadeAndMove()
function, passing the current index.
Example: http://jsfiddle.net/drWhE/
$(document).ready(function () {
// cache the LI elements
var $lis = $("#text > li");
var $aLis = $("#vivid_buttons > li");
function fadeAndMove( currentIndex ) {
var nextIndex = (currentIndex + 1) % 5;
var nextLi = $lis.eq( nextIndex );
nextLi.fadeIn(1000, function () {
$aLis.eq( currentIndex ).children('a').removeClass("active");
$aLis.eq( nextIndex ).children('a').addClass("active");
setTimeout(function () {
nextLi.fadeOut(1000, function() {
// Call fadeAndMove() passing nextIndex as the new currentIndex
fadeAndMove( nextIndex );
});
}, 4000);
});
}
// Get it started on index 0
fadeAndMove( 0 );
});
回答2:
Everything animates at once because your main loop keeps running while your fadeout timers wait four seconds.
Schematically, it goes like this (each line represents one second):
li1.fadeIn
li2.fadeIn |
li3.fadeIn | |
li4.fadeIn | | | Timers
li5.fadeIn V | | | wait four
li1.fadeOut V | | | seconds
li2.fadeOut V | |
li3.fadeOut V |
li4.fadeOut V
li5.fadeOut
li1.fadeIn
li2.fadeIn
.
.
.
etc, etc, ad nauseam.
To solve the problem, you need to chain the next call to fadeAndMove()
right after fading out the current item in your delayed function:
nextLi.fadeIn(1000, function () {
$("#vivid_buttons > li > a").removeClass("active");
nextA.addClass("active");
setTimeout(function () {
nextLi.fadeOut(1000);
fadeAndMove(i + 1);
}, 4000);
});
(Since that's a delayed call, it's not recursive. The infinite loop won't smash the stack.)
回答3:
Here's one way to get what you're looking for:
var $sentence_set = $('ul#text > li');
var $link_set = $('ul#vivid_buttons > li');
var highlight = function(which) {
var el = $sentence_set.eq(which - 1);
var position = el.prevAll('li').length;
$link_set.removeClass('active').eq(position).addClass('active');
$sentence_set.eq(position).siblings().fadeOut().end().fadeIn();
}
var loopcount = 0;
var repeater = setInterval(function() {
var theList = $('#text > li');
highlight(++loopcount % $sentence_set.length);
}, 4000);
Here's the fiddle.
And... the orange bar tells me patrick dw beat me to something similar. Well, here it is anyway.
来源:https://stackoverflow.com/questions/3893765/using-javascript-modulus-to-iterate-through-text-slider-with-for-loop