Home > Back-end >  I am trying to create a flight widget
I am trying to create a flight widget

Time:09-21

let mainid = document.getElementById("main_id");

function createcards(txt) {
  let cards = document.createElement("div");
  cards.classList.add("ex-1");
  cards.textContent = txt;
  return cards;
}

function addElements(parent, children) {

    children.forEach((e) => {
      setTimeout(() => {
        parent.appendChild(e); 
      }, 1000);
 
    });
  
}

items = [
  createcards(1),
  createcards(2),
  createcards(3),
  createcards(4),
  createcards(5),
];

addElements(mainid, items);

I want to append each child one by one. I meant by changing the speed of setTimeout. I tried doing it using for loop but it's not working as expected. please anyone help me?

CodePudding user response:

You have to create immediately-invoked function expression (IIFE) to create a closure around setTimeout.

let mainid = document.getElementById("main_id");

function createcards(txt) {
  let cards = document.createElement("div");
  cards.classList.add("ex-1");
  cards.textContent = txt;
  return cards;
}

function addElements(parent, children) {
    children.forEach((e, i) => {
      (function(index) {
        setTimeout(function() { parent.appendChild(e); }, i * 1000);
      })(i);
    });
}

items = [
  createcards(1),
  createcards(2),
  createcards(3),
  createcards(4),
  createcards(5),
];

addElements(mainid, items);
<div id="main_id" />

CodePudding user response:

Seem you a bit misunderstanding about the eventloop and how setTimeout work. Your code will delay 5 function, each 1000ms and then run those at the same time. For more you can check out this link

I tried with setInterval instead, you can check it out to see if it fit your problem

let mainid = document.getElementById("main_id");

function createcards(txt) {
  let cards = document.createElement("div");
  cards.classList.add("ex-1");
  cards.textContent = txt;
  return cards;
}

function addElements(parent, children) {
  const interval = setInterval(item => {
    if (!children.length) {
      clearInterval(interval)
      return
    }
    parent.appendChild(children[0])
    children.shift()
  }, 1000)
}


items = [
  createcards(1),
  createcards(2),
  createcards(3),
  createcards(4),
  createcards(5),
];

addElements(mainid, items);
<div id="main_id" />

CodePudding user response:

I found another solution, using setTimeout as you wish. Here what I changed is use for ... of instead of forEach. forEach will not work with async function as I just discovered when I try to solve your question. Ref: Using async/await with a forEach loop

let mainid = document.getElementById("main_id");

function createcards(txt) {
  let cards = document.createElement("div");
  cards.classList.add("ex-1");
  cards.textContent = txt;
  return cards;
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
async function addElements(parent, children) {
  for (let e of children) {        
    await sleep(1000);
    parent.appendChild(e); 
  }
}

items = [
  createcards(1),
  createcards(2),
  createcards(3),
  createcards(4),
  createcards(5),
];

addElements(mainid, items);
<div id="main_id" />

  • Related