-14

I want to create a loop for following js code. Please help me.

function fade90() { document.getElementById("myDiv").style.opacity="0.90"; setTimeout("fade80()", 100); }
function fade80() { document.getElementById("myDiv").style.opacity="0.80"; setTimeout("fade70()", 100); }
function fade70() { document.getElementById("myDiv").style.opacity="0.70"; setTimeout("fade60()", 100); }
function fade60() { document.getElementById("myDiv").style.opacity="0.60"; setTimeout("fade50()", 100); }
function fade50() { document.getElementById("myDiv").style.opacity="0.50"; setTimeout("fade40()", 100); }
function fade40() { document.getElementById("myDiv").style.opacity="0.40"; setTimeout("fade30()", 100); }
function fade30() { document.getElementById("myDiv").style.opacity="0.30"; setTimeout("fade20()", 100); }
function fade20() { document.getElementById("myDiv").style.opacity="0.20"; setTimeout("fade10()", 100); }
function fade10() { document.getElementById("myDiv").style.opacity="0.10"; setTimeout("hide()", 100); }

I write this. Is this correct? If not please fix this.

function cls_msg(){
    for (var i=1;i<10;i++)
    {
    setTimeout(document.getElementById("myDiv").style.opacity=100-(i*10), 100);
    }
}

Thanks

Musa
  • 96,336
  • 17
  • 118
  • 137
tranzme
  • 3
  • 1

2 Answers2

7

Before answering your actual question, I provide you a more proper solution to solve your fading issue since you try to do it overly complicated.

You should just modify the actual value and re-assign it to the style, no need to invoke all that methods and re-query the DOM.

function fadeIn( node, v ) {
    node.style.opacity = v || 1;

    if( v < 1 ) {
        setTimeout( fadeIn.bind( null, node, v + 0.1 ), 25 );
    }
 }

function fadeOut( node, v ) {
    node.style.opacity = v || 1;

    if( v > 0 ) {
        setTimeout( fadeOut.bind( null, node, v - 0.1 ), 25 );
    }
}

This is a pretty basic example of one way to accomplish the task. You can call it like

fadeOut( document.getElementById("myDiv") );

It's maybe an even better idea to let the browser / css transitions do the job, if don't need to support legacy browsers with animations. That could look like

function fadeIn( node ) {
    node.style.transition = 'all 400ms ease-in';
    node.style.opacity = 1;
}

function fadeOut( node ) {
    node.style.transition = 'all 400ms ease-in';
    node.style.opacity = 0;
}

Be aware that you might want to not just set transition, but also all the specific browser vendor prefixes like -ms-transition, -moz-transition, etc. for "not so legacy" browsers aswell.


To finally answer the question, you should use an Array to loop over multiple functions, this might look like

[ fade90, fade80, fade70, fade60,
  fade50, fade40, fade30, fade20,
  fade10, hide ].forEach(function( method, i, arr ) {
      setTimeout(function() {
          if( typeof arr[ i+1 ] === 'function' ) {
              !i && method();
              setTimeout( arr[ i+1 ], 25 * i );
          }
      }, 25);
});

Be aware that you also should re-write those methods also, those should not call setTimeout for themselfs, also they should not re-query for the target node. I just wanted to give you an example of my approach.

jAndy
  • 231,737
  • 57
  • 305
  • 359
  • 1
    +1, elegant, nicely done – C.. Mar 04 '13 at 15:45
  • Or you could skip the `.bind()`, and do `setTimeout(fadeIn, 25, node, v + 0.1);` It would need a shim, but then so would `.bind()`. But +1. – the system Mar 04 '13 at 15:56
  • @thesystem: True, I like to forget that `setTimeout` has an implied curry mechanism. But as you mentioned, its not that cross-browser aswell. – jAndy Mar 04 '13 at 16:04
  • Hmmm... you lost me on the last example. First, you forgot to define `i`, but easy fix. Beyond that, it seems the index `0-8` methods will all be invoked after `25ms`, and then methods `1-9` will all be invoked `25ms` later. So you're invoking most of them twice, and not staggering their invocations. Please correct me if I'm wrong. Perhaps you intended to use an `if/else` for the invocations, and a `* i` for the `setTimeout`s ? – the system Mar 04 '13 at 16:40
  • ...I may just be confused. – the system Mar 04 '13 at 16:41
  • I was wrong about everything being invoked twice. Was turned around on the `!i`, but the timing does need to be staggered. Assuming you just forgot the `* i` and the parameters `, i, arr` – the system Mar 04 '13 at 16:56
2

Not sure what you are asking, but may I suggest something a little tidier?

function fade(n, el) {
  el.style.opacity = n;
  n = n - 0.1;
  if (n.toFixed(1) > 0) {setTimeout(function() {fade(n, el);},100);}
  else {setTimeout(function() {hide(el);}, 100);}
}

function hide(el) {
  el.style.visibility='hidden';
}

and then initially call

fade(0.9, document.getElementById("myDiv"));

eg: http://jsfiddle.net/XY4yM/

C..
  • 802
  • 4
  • 16