Autor Zpráva
Hitman
Profil
Dobrý den,

už asi hodinu řeším zdálnivě jednoduchý problém, ale stále nemůžu přijít na to, jak v javascriptu realizovat zastavení běhu programu a následné pokračování. Mám cyklus, kde vypisuji hodnoty na obrazovku a potřebuji aby se vykreslovali postupně.

do {
    i++;
        document.write("NĚCO");
      pause(500);
    } while(i < n);

Moje představa je taková, že se vypíše "něco", 0,5s program počká a poté pokračuje v cyklu dokud platí podmínka znovu po 0,5s vypíše něco atd. Zkoušel jsem setTimeout(), vložit ten výpis do funkce atd. Chápu to tak, že setTimeout() funguje tak, že to něco obsažené v setTimeout zavolá za určitou dobu. Čili v mém případě zavolá třeba 10x něco za 0,5s, ale všechny ve stejnou dobu. Já to potřebuji vypsat postupně s odstupem mezi sebou. Je to vůbec v JS možné? Díky

//Jde mi o vykreslování jednoduché grafiky, ale postupně, aby uživatel viděl jak to přibývá
RastyAmateur
Profil
Hitman:
Použij https://developer.mozilla.org/en/DOM/window.setInterval
Hitman
Profil
Můžeš mi to prosím přepsat pro můj příklad? Nějak tomu pořád nerozumím a přijde mi to strašně komplikované oproti třeb Cčku...díky :-)
Bubák
Profil
Tohle je typické začátečnické (taky jsem si tím prošel) nevhodné použití document.write Na co stránka čeká

To, co požaduješ, jde udělat mnoha způsoby, následující výčet není kompletní:
• použít GIF animaci
• použít CSS animaci
• udělat JS animaci skrze změnu CSS display: none nebo visibility: hidden
• udělat JS animaci skrze změnu src obrázku nebo obrázků
• udělat JS animaci, skrze změnu DOM přidávat další IMG
• použít SVG animaci

Pokud použiješ JS, tak si nastuduj window.setInterval třeba z odkazu, co cem dal RastyAmateur, doporučuji vyhnout se w3schools.com.
Hitman
Profil
Jde o to, že na základě algoritmu potřebuji různými cestami vykreslovat čtverec/obdelník. Ten je složený z třeba 5x5 bloků, nebo také 20x20 bloků, dle zadání uživatele. Nebude se vykreslovat lineárně, ale třeba nejdříve diagonála, potom nahoru, potom doleva atd.

Jediné co mi tam chybí je to zpomalení....

Čili z Bubákových řešení mi připadá asi nejvhodnšjší JS se změnou display. Musím si ale vytvořit čtverec na začátku a jednotlivým buňkám dát class=t11, class= t12 atd., kde čísla představují pozici x,y.

Potom při procházení scriptu odkrývat prvky .class("t"+pozice_x+pozice_y)

Ten druhý bod "udělat JS animaci, skrze změnu DOM přidávat další IMG" bych uměl udělat. Nyní jsem tam měl:

 document.write("<span style='left:"+(j*10)+"px;top:"+(i*10)+"px'>X</span>");

Jenže je problém jak mezi jednotlivými write, nebo přidáváním dalších IMG jak píše Bubák, udělat pauzu, vykreslí se vše najednou....

Nebude lepší setTimeout? Bohužel ani ten mi nefunguje:

function vypis(i){
document.write("A"+i);
}

do {
    i++;
        window.setTimeout("vypis(i)",  i*1000);
    } while(i < n);

Mi vypíše sice několikrát, ale pouze poslední prvek.....

Díky
Keeehi
Profil
Hitman:
var n = 5;

function vypis(i){
    i++;
    
    document.write("A"+i);
    if (i < n) {
        window.setTimeout(function(){vypis(i)},  i*1000);
    }
}

vypis(0);

Kdyby jsi se chtěl ptát, proč A1 se vypíše, následně zmizí a od A2 to už zůstává, tak odpověď je, že ta to může document.write o které se zmiňuje Bubák ve [#4]. Používej console.log(), to je na debuggování mnohem lepší.
Hitman
Profil
Díky za odpověď. To je pro mě asi nepoužitelné, pokud tam mám více cyklů a navíc ošetřovat ten první mizející prvek....

Nějak jednodušeji to na webu asi nepůjde že? Třeba v jquery?
Keeehi
Profil
Hitman:
Mizející prvek je jen artefakt volání document.write. Což je něco, co vůbec nepotřebuješ. Máš to tam jen pro otestování funkčnosti. Což chápu, že začátečníka napadne jako první ale nutné to vůbec není. Když budeš na testovací výpisy používat console.log, budeš mít život hned jednodušší.
Hitman
Profil
No tam jde o to, že já tam ten výpis potřebuji i v ostré verzi. Mělo by to na web vykreslit obrazec složený z čtverečků třeba 10x10px, ale ne lineárně, ale různými směry v podstatě takkový "had". Algoritmus mám po částech otestovaný, ale je problém s tím výpisem "po jednom", ne jako celé najednou, aby bylo vidět jak to celé přibývá. To pause by bylo úplně ideální....ale tam je problém že se JS načítá celý při stahování stránky, takže žádná pauza jako v offline programu tam možná není..
RastyAmateur
Profil
Hitman:
Nejsem si úplně jistý, v čem vidíš problém. Máš funkci setTimeout, která ti po určité době zavolá nějakou funkci. To je vlastně vše, co potřebuješ, ne? Budeš mít funkci, která ti vykreslí jednu část obrázku a pokud je ještě něco, co by měla vykreslit, nastaví timeout tak, aby za určitý časový úsek ta funkce zavolala rekursivně zase "sama sebe" (respektive aby funkce setTimeout zavolala tu tvojí funkci. To slovo "rekursivně" jsem použil spíše proto, aby bylo jasné, že z té samé funkce nastavíš, aby se ta samá funkce zavolala zase).

Takže pseudokód:
function draw() {
  appendNextPart()
  if (nextPartExists()) {
    setTimeout( draw, 1000 )
  }
}

// Start the function for the first time
draw()

Problém nastane, když už na začátku nebude co kreslit. Takže možná by stálo nad tím se zamyslet, jestli nedát hned na začátku podmínku, jestli je co kreslit a až pak vykreslit a nastavit timeout. Ale to už jsou jen implementační detaily.


Hitman:
Mělo by to na web vykreslit obrazec složený z čtverečků třeba 10x10px, ale ne lineárně, ale různými směry v podstatě takkový "had"
Dobře, tak předpokládám, že máš nějakou logickou datovou strukturu:
objectsToDraw = [
  { top: 20, left: 40; width: 10; height: 10; },
  { top: 50, left: 10; width: 15; height: 15; },
]

Pak ta funkce appendNextPart() z pseudokódu výše bude něco jako:
function appendNextPart() {
  obj = objectsToDraw.pop()
  container.append(createElement(top=obj.top, left=obj.left, ...))
}

A podmínka nextPartExists() je již prosté objectsToDraw.length > 0

Snad tě nemate ten pseudokód, ale nechci ti to tu naservírovat. Tak by jsi se to nenaučil. Keeehi ti již poradil dostatečně, já ti to víceméně zopakoval...
Keeehi
Profil
Hitman:
No tam jde o to, že já tam ten výpis potřebuji i v ostré verzi.
Nepotřebuješ. document.write v ostré verzi nepotrebuješ k ničemu a v testovací verzi můžeš použít console.log
Proč nepotřebuješ v ostré verzi document.write? Protože ty nepotrebuješ do stránky nic vypisovat, ty tam budeš mít už vsechny čtverce predem připravené a budeš je jen zviditelňovat.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0