Az igazi cím inkább a "Hogyan írjunk ki egy szöveget JavaScript-ben betűnként?" lenne, de túl hosszúnak tűnt :) Mai napon sok vergődésembe került a címben említett problémát megoldani, pedig már tanultam is róla, dehát könnyen felejt az ember. Csináltam ma egy design-t és úgy gondoltam milyen jó lenne, ha egy kis emberke lenne rajta, és mellette egy buborék 'amiben beszél'. Ez így szép is meg jó is, de a html ezzel már nem tud mit kezdeni, be kell vetni a javascript tudást. A getElementById-ig ment is a dolog, aztán jött a probléma, hogyan mondjuk meg, hogy annak az elemnek a szövegét akarjuk változtatni? :)

Első megoldásként olyasmi szép függvényeket találtam a problémára: createTextNode, appendChild, replaceChild, removeChild, stb. Tulajdonképpen a szöveg beírásával nem is volt gond, az működött, de akartam egy extra fícsört, hogy bizonyos időközönként történjen meg a 'beszéd' újra, ehhez viszont az kéne, hogy törölni tudjam az eddigi szöveget. Valahol találtam is még ilyen deleteData függvényt is, de nem igazán működött, a replaceChild-al az volt a gond, hogy kell neki, hogy mit minek a helyére tegyen, és itt még a mit nem is kérdéses, de a minek a helyére az elég problémás, hiszen nem egy elemről van szó, csak szövegről, és így nem tudtam mit csináljak, ekkor léptem át a DOM csodálatos világába [bár ha most ez hülyeségnek tűnne, akkor csak azért van, mert nem tudom hol a határ a JS és DOM között:]

A megoldást tehát egy nagyon egyszerű elem jelentette, az 'innerHTML', ez esetünkben annyit tesz, mint egy form elemeinél a 'value', megkaphatjuk a mező értékét és módosíthatjuk is vele könnyedén, csakhogy utóbbi csak formokban alkalmazható, egyéb elemeken nem igazán, van helyette 'innerHTML', csak rá kell jönni, hogy van, és innentől kezdve pofonegyszerű a feladat :)

Lássuk tehát a megvalósulást. Először is kell egy függvény, amit a body onload="" metódusából hívhatunk, stilszerűen init()-nek nevezhetjük, tehát a html-ben ennyi változtatás szükséges:

<body onload="init()">

Ezután az init()-ben egyszerűen meghívjuk a függvényünket, nálam az 'udv' nevet kapta, mivel üdvözlő szövegről van szó. A 0-ás paraméteréről mindjárt szót ejtek. Tehát az udv függvényünket indítjuk, ez egy változóba elteszi nekünk a kívánt szöveget. A következő sor miatt már el kell áruljam, hogy az 'n' paraméterünket arra használjuk, hogy az n. karaktert vegyük ki az előbb specifikált szövegből, hiszen az jön soron a kiiratásban. Ekkor tehát végeznünk kell egy tesztet, hogy odaértünk-e már az utolsó utáni betűhöz, mivel ilyen nincs, ezért nyílván ekkor már nem akarunk tovább betűket kiírni tovább. A kiírás folyamata a következő:

  1. eltesszük egy változóba a módosítani kívánt html elem referenciáját
  2. előállítjuk a soron következő karaktert [az n.-et]
  3. kiírjuk az új betűt a képernyőre

A következő betű kiírásához rekurzívan meg kell hívni a függvényünket, azzal a különbséggel, hogy az n paramétert most már (n+1)-nek választjuk. A setTimeout('függvényNeve(paraméterei)',[a szünet hossza milimásodpercben]) paraméterezése miatt én egy külön változóban szoktam előbb létrehozni az első paramétert, mivel egy szöveget vár, és voltak már problémáim belőle amikor ott helyben akartam összerakni a függvényhívást :) szóval, ha megfogadtok egy jó tanácsot, akkor ha paraméterezni kell a függvényt, akkor előbb egy változóban hozzátok létre, úgy nem lehet gond. A szünet hosszát pedig én 100ms-re állítottam, bár ennyivel nem sokan tudnak gépelni szerintem, az átlag gépelési időhöz inkább a 200-300 lenne az ideális, de kipróbáltam és szép meg jó, tényleg olyan, mintha valaki mást látnék szenvedni, ahogy gépel, de mivel az olvasási sebességünk gyorsabb a gépelésinél ezért a 100 olyan köztes megoldásnak jó szerintem :) Aki a végső határokat szeretné feszegetni az próbálkozhat a 40-41ms-sel [a szemünk 24-25 képet lát másodpercenként, tehát 1000/25=40ms idő az teljesen korrekt, annak aki esetleg js-ben mozgást kívánna létrehozni, bár a mozgásoknál inkább 30ms a szokásos, de erről majd egy másik cikkben:]

Visszatérve: meghívjuk a setTimeout-ot és a beállított idő múlva meghívódik az (n+1). függvényünk, és írja szépen tovább a betűket. Amiről még nem esett szó, hogy mi van, ha elfogytak a betűk. Ki-ki belátása szerint csinál amit akar, én alkottam egy cls() függvényt, gondolom nehéz kitalálni, hogy mi célt szolgálhat :) Említettem a cikk elején, hogy szerettem volna ha többször is megtörténik ez a 'gépelés', ehhez törölni kell az eddig beírt szöveget, majd újraindítani a folyamatot, a törlés mint látható egyszerűen csak annyi, hogy a [kiválasztott elem].innerHTML tagját egy üres szöveggel tesszük egyenlővé. A kódunk véglegesen tehát ilyen formát ölt:

/* Iniciálunk, futtatunk...futtatunk, törlünk, futtatunk.. */
function init() {
 udv(0);
}
function udv(n) {
 var t = 'Üdvözöllek az oldalon! Köszönöm, hogy meglátogattál.';
 if (n!=t.length) {
  var h = document.getElementById('header');
  h.innerHTML += t.charAt(n);
  var f = 'udv('+(n+1)+')';
  setTimeout(f,100);
 } else setTimeout('cls()',30000);
}

function cls() {
 var h = document.getElementById('header');
 h.innerHTML = '';
 udv(0);
}

Várok további ötleteket, hogy mikre vagytok kíváncsiak javascript terén, és persze ha felmerül valami megoldott probléma a házam táján közlöm veletek :)