• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Pętla w pętli i setTimeout / setInterval

VPS Starter Arubacloud
+1 głos
513 wizyt
pytanie zadane 26 kwietnia 2021 w JavaScript przez molik Użytkownik (950 p.)

Chodzi o to, że chcę stworzyć tzw pismo maszynowe i aby po jednej literce dodawały się do strony. Chciałbym to zrobić na pętlach, ale nie rozumiem dlaczego setTimeout/setInterval nie działa po mojej mysli.. Może ktoś mi to pomóc zrozumiec? 

`const spnText = document.querySelector('.text');
const spnCursor = document.querySelector('.cursor');
const text = ['tekst1', 'tekst2', 'tekst3'];
let counter = 0;

const addLetter = () => {
  for(let i = 0; i < text.length; i++){
    while(counter < text[i].length){
      setInterval(() => {
        spnText.textContent += text[i][counter];
        counter++;
      }, 2000);
    }
  }
}
addLetter();`

 

komentarz 26 kwietnia 2021 przez Bizuma Gaduła (3,650 p.)
Zdradź proszę jaka jest "twoja myśl" w takim razie, bo tak to nie wiem do czego dążyć.

3 odpowiedzi

+1 głos
odpowiedź 26 kwietnia 2021 przez overcq Pasjonat (21,540 p.)
wybrane 26 kwietnia 2021 przez molik
 
Najlepsza

Na przykład tak:

const spnText = document.querySelector(".text");
const text = ["tekst1", "tekst2", "tekst3"];
let text_i = 0;
let text_ii = -1;

const interval = setInterval(() => {
  if (++text_ii == text[text_i].length) {
    if (++text_i == text.length) {
      clearInterval(interval);
      return;
    }
    text_ii = 0;
  }
  spnText.textContent += text[text_i].charAt(text_ii);
}, 2000);

 

komentarz 26 kwietnia 2021 przez molik Użytkownik (950 p.)
ech... jak tak analizuje to spoko.. ale coś mi do głowy nie chce to wejść ;p

Dzięki za rozwiązanie pozdrawiaam :)

może jeszcze ktoś inny sposób zna?
+1 głos
odpowiedź 26 kwietnia 2021 przez Anedroid Obywatel (1,530 p.)
Zrób sobie funkcję, która będzie zawierać w sobie setTimeout na samą siebie.
komentarz 26 kwietnia 2021 przez molik Użytkownik (950 p.)
Na sama siebie?
2
komentarz 26 kwietnia 2021 przez Anedroid Obywatel (1,530 p.)

Nie wiem dokładnie co ma robić twój skrypt, ale widzę tu błąd. Polecenia setTimeout i setInterval nie czekają aż upłynie dany czas. Tak robią funkcje typu sleep w php lub c++. W JavaScript zadanie jest odkładane na za 2 sekundy i natychmiast wykonywane kolejne, w tym przypadku kolejna iteracja pętli.

Do wykonywania czegoś w pętli co 2 sekundy użyłbym takiej konstrukcji:

let counter = 0;
function addLetter() {
    if (counter >= text[i].length) {
        return;
    }
    spnText.textContent += text[i][counter];
    couter++;
    setTimeout(addLetter, 2000);
}
addLetter();

 

komentarz 27 kwietnia 2021 przez overcq Pasjonat (21,540 p.)

Pytanie tylko, czy przeglądarka www pozwoli rozpocząć wykonywanie kolejnej instancji funkcji ustawionej w setInterval przed wykonaniem się poprzedniej...

Jeśli ustawię czas w setInterval na 1 milisekundę lub 0, i sprawdzam w CodePen.io, to nadal kolejność dodawanego tekstu jest zachowana.

+1 głos
odpowiedź 27 kwietnia 2021 przez VBService Ekspert (251,210 p.)
edycja 27 kwietnia 2021 przez VBService

Można jeszcze użyć: Bringing Sleep to Native JavaScript , How to make your JavaScript functions sleep

Przykład

<div class="console"></div>
*, *:before, *:after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
body {
  margin: 0;
  padding: 0;
  border: 0;
}
.console {
  width: 90vw;
  height: 50vh;
  margin: 1em auto;
  padding: 1em;
  border-radius: 0.25em;
  box-shadow: 0 0 2px 2px silver;
  background-color: black;
}
.console .cmd-text {
  color: #1ff042;
  display: block;
  font-family: monospace;
  font-weight: bold;
  text-transform: uppercase;
  font-size: 1.225em;
  letter-spacing: 0.15em;
  text-shadow: 1px 1px 2px green, 1px 2px 4px limegreen, 1px 2px 4px green;
  padding-bottom: 0.5em;
}
.console .cmd-line::before {
  content: '>';
  padding-right: 0.5em;
  color: yellow;
}
.console .cmd-line::after {
  display: inline-block;
  vertical-align: -0.15em;
  width: 0.75em;
  height: 1em;
  margin-left: 5px;
  background: #1ff042;
  opacity: 1;
  box-shadow: 1px 1px 1px rgba(31, 240, 66, 0.65),
    -1px -1px 1px rgba(31, 240, 66, 0.65),
    1px -1px 1px rgba(255, 240, 66, 0.65),
    -1px 1px 1px rgba(31, 240, 66, 0.65);
  -webkit-animation: cursor-blink 1.15s infinite;
  -moz-animation: cursor-blink 1.15s infinite;
  animation: cursor-blink 1.15s infinite;
  content: '';
}

@keyframes cursor-blink {
  from { opacity: 1; }
  20%  { opacity: 1; }
  30%  { opacity: 1; }
  40%  { opacity: 0; }
  50%  { opacity: 0; }
  60%  { opacity: 0; }
  70%  { opacity: 1; }
    to { opacity: 1; }
}

.console .cmd-line-enter::before {
  content: '>';
  padding-right: 0.5em;
  color: yellow;
}
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function writeOnConsole() {
  const cmd_text = [
    'Lorem Ipsum jest tekstem stosowanym jako przykładowy wypełniacz w przemyśle poligraficznym.',
    'Został po raz pierwszy użyty w XV w. przez nieznanego drukarza do wypełnienia tekstem próbnej książki.',
    'Pięć wieków później zaczął być używany w przemyśle elektronicznym, pozostając praktycznie niezmienionym.',
    'Spopularyzował się w latach 60. XX w. wraz z publikacją arkuszy Letrasetu, zawierających fragmenty Lorem Ipsum.'
  ];

  const board = document.querySelector('.console');
  await sleep(1000);


  for (let i=0; i<cmd_text.length; ++i) {
    const span = document.createElement('span');
    span.setAttribute('class', 'cmd-line cmd-text');

    board.appendChild(span);
    await sleep(1000);

    for (let j=0; j<cmd_text[i].length; ++j) {
      span.textContent += cmd_text[i][j];
      await sleep(30);
    }

    await sleep(600);
    if (i<cmd_text.length - 1) {
      span.classList.remove('cmd-line');
      span.classList.add('cmd-line-enter');
    }
  }
}

window.onload = () => {
  writeOnConsole();
}

1
komentarz 29 kwietnia 2021 przez molik Użytkownik (950 p.)

o kur... :D teraz to burza mozgow ;D smiley ale dziękuję ślicznie ;p

Podobne pytania

0 głosów
1 odpowiedź 481 wizyt
0 głosów
1 odpowiedź 392 wizyt
0 głosów
1 odpowiedź 296 wizyt
pytanie zadane 19 marca 2020 w JavaScript przez kubaa322 Użytkownik (710 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...