0

I have an extremely simple script which is supposed to grab every element with and id="d", then iterate through each of those elements; grabbing the value of their data-color.

Each time it loops through, it is supposed to change the background of the document to those values, then alert the value.

It would work, and grab all of the values, and output them; one after the other. However, due to the alerts being too quick for the page to actually change the background color, I had to put the alerts within a setTimeout so that the document could change color, wait 250 milliseconds, THEN alert the value. When I did this though, it would only ever get the last elements data-color value and alert it.

This is my JavaScript:

var selector = document.querySelectorAll("#d");

for(var i = 0; i < selector.length; i++){
    var did = selector[i].getAttribute("data-color");

    document.body.style.background = did; // set background to data-color value
    setTimeout(function(){ // wait 250 milliseconds (this is where it breaks)
        alert(did); // THEN alert the value of data-color
    }, 250);
}

And the HTML:

<div data-color="green" id="d"></div>
<div data-color="blue" id="d"></div>
<div data-color="red" id="d"></div>

Why does this happen? Thanks.

GROVER.
  • 4,071
  • 2
  • 19
  • 66
  • 4
    Ids must be unique. Also, all your timeouts will run at the same time, since they all start at the same time. Finally, `did` in your alert will always have its last value by the time the timeouts run. –  Jan 07 '17 at 05:53
  • @torazaburo but, it worked beforehand when I removed `setTimeout`? So it mustn't be something to do with the `id`, rather the timeout? Then shouldn't it just be repeating green?.. Apologies if it sounds a bit dumb, but I'm very new to JavaScript – GROVER. Jan 07 '17 at 05:54
  • 1
    it takes longer than 250ms to dismiss the alert, so I am not sure this will get the desired output - what about just logging the colour change? - oh, and the issues with `id`s will not cause this but it is another coding standard/validity issue (they are supposed to be unique; you can change them to classes instead) – blurfus Jan 07 '17 at 06:10
  • 1
    @ochi ohh okay :-) I was not aware of this. I have been using `id`'s due to some elements being proceduraly generated through `PHP`, so I am unable to change the `classes`'s or `id`'s – GROVER. Jan 07 '17 at 06:12
  • @OlegEstekhin there may be another answer, but just because there is, it doesn't mean I understand it. Hence, the reason I created a question. – GROVER. Jan 07 '17 at 07:42

1 Answers1

1

I changed the ids for classes - also changed the setTimeout for setInterval

I am not sure if this is the desired outcome but perhaps you can let me know more precisely what the desired outcome is :)

See demo below

var selector = document.querySelectorAll(".d");
var i = 0; // index for traversing the array of elements

// wait 2000 milliseconds (2 secs)
var intervalHandle  = setInterval(function() {
  var did = selector[i].getAttribute("data-color");
  // set background to data-color value
  document.body.style.background = did;
  // THEN log the value of data-color
  console.log(did);
  
  // if there are more items in the array, increment index so 
  // that next interval will use the next element in array
  if (i < selector.length-1) {
    i++;
  } else {
    //otherwise, clear the interval to stop
    clearInterval(intervalHandle);
  }

},  2 * 1000); // 2 secs
<div data-color="green" class="d"></div>
<div data-color="blue" class="d"></div>
<div data-color="red" class="d"></div>
blurfus
  • 13,485
  • 8
  • 55
  • 61