user2599381
user2599381

Reputation: 757

Javascript to fade text in, one word at a time, works with one div, but not multiple divs?

I'm trying to fade in one word at a time from a div. The below code works fine for one div but when I have multiple divs, it does not do it sequentially.

Here is the fiddle : http://jsfiddle.net/zlud/6czap/110/

Can anyone see an obvious problem? Any suggestions to print one line after the other would be greatly appreciated. (So the text in the second div will be printed after the first div is done.)

<html>
<div class="example">These are some words that </br> should be faded in one after the other.</div>
<div class="example"> No way some words that </br> should be faded in one after the other.</div>
</html>

JavaScript

var $el = $('.example').map(function () {
return this;
}).get();

$el.forEach(function (eachdiv){
        
var  text = $(eachdiv).text(),
words = text.split(" ");
var html = "";

for (var i = 0; i < words.length; i++) {
    html += "<span>" + words[i] + " </span>";

        $(eachdiv).html(html).children().hide().each(function(i){
           return $(this).delay(i*500).fadeIn(700);``
        });        
    }
});

Upvotes: 3

Views: 3185

Answers (3)

PSL
PSL

Reputation: 123739

How about this?

I am assuming you dont need a delay in animation, instead you need them to appear one after the other.

var words, $el;
var arrEl = [];

// loop through each div and populate the array with the container (div) element and its text content split
$('.example').each(function(){
    var $this = $(this);
    arrEl.push({el:$this,words : $.trim($this.text()).split(" ")});
    $this.empty();
});

//This will the startup function  
function fadeIn(){
    var len = arrEl.length,  obj = arrEl.shift() || {}; //get the top item from array and remove it from the array using array.shift
    $el = obj.el; //get the container from the item
    words = obj.words; //get the array of words
    //if there are any items in the array start the animation process for this item.
    if(len)  window.setTimeout(transitionElement, 0); 
}

function transitionElement(){

    var wlen = words.length,
    span = $('<span/>', {'class':'hide'}).append(" " + words.shift()); //remove and get the top text string from the word array wrap it in span with a class "hide" which will hide it by default

    window.setTimeout(function(){
        if(wlen)  //if words are available anymore then call show word
           showWord(span);
        else //else call fadeIn to process the next container in the arrEl array of items
            fadeIn();
    },0);
}

function showWord(span){
     span.appendTo($el).fadeIn(500, transitionElement); // append the span to the container with an animation duration of 500ms and in the complete callback of this invoke transitionElement to process the next word or next item. Here there is no delay required since this will invoked only when the transition of first word is completed
}
//Start animation process
fadeIn();

Fiddle

Upvotes: 2

undefined
undefined

Reputation: 2101

Jquerys animation functions have a callback in the parameter list. This callback will be executed after the animation completes. Or maybe it's that i is passed by reference.

Upvotes: 1

inquam
inquam

Reputation: 12942

You should pick on div at a time to work on and continue to the next one ones the first is done. Now you attach the delay and fade-in to each word in each div at the same time. Initiate the animation of the second div by a trigger when the first one is done or something like that?

Upvotes: 0

Related Questions