0
function createDivs(){ 
var styleHash = {};
vertical=0;
horizontal=0;
var h;
var aDiv
var colour;
var groupStyle;
    for(key in elHash){ 
      h=elArr[0][zIndex[key]]/elHash[key];
      colour = randomColor();
      setLocation(h,elHash[key]);
      var container = document.getElementById('container');
      styleElements(container,'width',(scrnWidth-40)+'px');
      styleElements(container,'height',(scrnHeight-200)+'px');
      aDiv = implementDOMelement(container,'div', '');
      groupStyle = function() {       
          styleElements(aDiv ,vposition,vertical+'px');
          styleElements(aDiv ,hposition,horizontal+'px');
          styleElements(aDiv ,'backgroundColor', colour);
          styleElements(aDiv ,'width', elHash[key]+'px');
          styleElements(aDiv ,'height', h+'px');
          styleElements(aDiv ,'zIndex', zIndex[key]);
          if (colour =='#ffffff'){styleElements(aDiv ,'border', 'solid');}
      }
      setTimeout( groupStyle ,1000);
    }
}

function randomColor(){
   var colorR;
   var colorG;
   var colorB;
   colorR = randomNumber(0,255);
   colorG = randomNumber(0,255);
   colorB = randomNumber(0,255);
   return 'rgb('+colorR+','+colorG+','+colorB+')';
}

function implementDOMelement(parentNode, elementType,innHTML, attributes ){//
    var element = document.createElement(elementType);
    for (key in attributes){
      element.setAttribute(key,attributes[key]);
    }
    element.innerHTML = innHTML;
    parentNode.appendChild(element);
    return element;
}

function styleElements(aNode,cssProperty,cssVal){
    aNode.style[cssProperty]=cssVal;
}

Why is 'setTimeout' executed only once instead on every iteration? Well my goal is to pop a div on every sec! Did't put all of the code but it works fine without setTimeOut and groupStyle(code not in a function)

10x for your help , BR

2
  • But it is executed on every iteration. I don't get it. Commented Jun 8, 2011 at 22:21
  • I guess I don't get it either, but let me put all of the code Commented Jun 8, 2011 at 22:24

3 Answers 3

3

It is executed on every loop, but all 10 of them are executed at the same time. The loop goes through the list very fast, and by the time its done looping, not a single timeout has probably occured.

If you are looking to have the aFunc executed every 1 seconds, then use setInterval or alternatively increment the setTimeout time by 1000 after each iteration.

Sign up to request clarification or add additional context in comments.

Comments

2

*psychic debugging* ...I believe you mean this:

var i = 0;

for(key in hash){
  var aFunc = function() {}
  setTimeout(aFunc, 1000 * i++);
} 

Your function calls all happen immediately after each other because the for loop takes no time to run and therefore all timeouts are set to approximately the same time. You need to increase the timeout with every iteration to get a once-every-second effect. Or you use setInterval()/clearInterval().

10 Comments

I've put a part of my original code and what I'm after maybe that will give an extra clue
@kidwon You may be missing the fact that setTimeout() returns immediately - it does not wait at all. The payload function will be placed on a stack and executed separately when the given time has passed.
I see a few weird parts on your code, like "elHash" is never defined o_O (I will assume it to be a global variable). But other than that, Tomalak's answer seems to fit your intent. Give it a try.
Well what should I do , I really have to address the hash elements so I need the for in loop? Is there any solution?
The setTimeout() actually takes the last computed function... Even if you put it in an array like this. I'm currently trying several things to get it to do what we want, but it either does that same (wrong) thing or fails silently... frustrating! An interesting issue nonetheless.
|
1

Look at this, it might just be the answer you are looking for:

setTimeout in for-loop does not print consecutive values

In your case: aDiv is pointing always to the last div of the loop. This is my guess why it looks like it only triggers once.

a simple solution for your code should be along this lines:

  groupStyle = function() {       
      styleElements(aDiv ,vposition,vertical+'px');
      styleElements(aDiv ,hposition,horizontal+'px');
      styleElements(aDiv ,'backgroundColor', colour);
      styleElements(aDiv ,'width', elHash[key]+'px');
      styleElements(aDiv ,'height', h+'px');
      styleElements(aDiv ,'zIndex', zIndex[key]);
      if (colour =='#ffffff'){styleElements(aDiv ,'border', 'solid');}
  }
  setTimeout( groupStyle ,1000);
  //replaced with:

  // I will assume vposition and hposition were supposed to be strings not variables
  doGroupStyle(aDiv, vertical, horizontal, elHash, key, zIndex, colour);

  // then create the doGroupStyle function
  function doGroupStyle(aDiv, vertical, horizontal, elHash, key, zIndex, colour) {
    setTimeout(function() {
      styleElements(aDiv ,'vposition',vertical+'px');
      styleElements(aDiv ,'hposition',horizontal+'px');
      styleElements(aDiv ,'backgroundColor', colour);
      styleElements(aDiv ,'width', elHash[key]+'px');
      styleElements(aDiv ,'height', h+'px');
      styleElements(aDiv ,'zIndex', zIndex[key]);
      if (colour =='#ffffff'){styleElements(aDiv ,'border', 'solid');
      }, 1000 * key);
    }
  }


// or an alternative approach as passcod suggested:
(function(aDiv, vertical, horizontal, colour, elHash, key, h, zIndex) {
groupStyle = function() {       
    styleElements(aDiv ,'vposition',vertical+'px');
    styleElements(aDiv ,'hposition',horizontal+'px');
    styleElements(aDiv ,'backgroundColor', colour);
    styleElements(aDiv ,'width', elHash[key]+'px');
    styleElements(aDiv ,'height', h+'px');
    styleElements(aDiv ,'zIndex', zIndex[key]);
    if (colour =='#ffffff'){styleElements(aDiv ,'border', 'solid');}
};
setTimeout(groupStyle ,1000 * key);
})(aDiv, vertical, horizontal, colour, elHash, key, h, zIndex);

Haven't tested it so you maybe have to modify it a bit. But that's the idea behind it.

4 Comments

Hey, what if key isn't numeric? Well, I found that using an inline closure works. It's derived from the answer you linked to.
@passcod if key is not numeric then you make your own counter :) I assumed it was because he said he used Tomalak's suggestion which required it to be numeric. Also his request for the divs to "pop a div on every sec". Your solution is the first thing i came across :) very clean but it all happens at once.
@passcod here is a version of yours with the counter added. And thanks for showing me jsfiddle.net didn't know about it ^^
Oh right, I misread that comment. Sorry! Also, you forgot the i in the function definition in that last fiddle... here it is fixed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.