Autor Zpráva
quatzael
Profil
Řeším trochu schizofrenní situaci. V cyklu projíždím hodnoty z JSON, a v každým cyklu si na základě těch hodnot vytvořím proměnnou itemname, a pak následuje podmínka jestli element s takovým Id existuje. Podmínka se splní (i když by zrovna takový element existovat neměl) a v následujícím kroku mi to hlásí chybu, protože element s daným Id skutečně neexistuje..

var checkelem = document.getElementById(itemname);

if (checkelem)
{
//nějaký kód
document.getElementById(itemname).style.borderColor = //něco
}



Už jsem na to asi přišel..

Mám tam uvnitř funkci:
var interval = setInterval(function() .. 
a uvnitř to nebere tu globální proměnnou itemname..

Nevíte někdo jak se dá použít ta proměnná uprostřed funkce jako globální?
weroro
Profil
Neskúšal si ju vkladať ako argument do tej setInterval funkcie?
quatzael
Profil
weroro:
Ne, ani nevím jak se to tam vkládá..

Jen takhle:
var interval = setInterval(function(itemname) .. ?

A v tý funkci jí můžu použít pod stejným názvem?


weroro:
Zkusil jsem a nefunguje..
Chamurappi
Profil
Reaguji na quatzaela:
uvnitř to nebere tu globální proměnnou itemname
Ale bere. Jen jí to bere v době, kdy se načasovaná funkce volá, a to už má zřejmě jinou hodnotu. Viz lexikální uzávěr.
Edit: Pokud jsem se netrefil, dodej živou ukázku.

Mimochodem, pamatuješ, co jsem ti psal o tom, že diskuse není chat? Když něco vlepíš do příspěvku dodatečně, adresát si toho nemusí všimnout. Posílej příspěvky v kompletní podobě najednou.
quatzael
Profil
Chamurappi:
Ale bere. Jen jí to bere v době, kdy se načasovaná funkce volá, a to už má zřejmě jinou hodnotu.
Jo asi máš pravdu, vypadá to, že v tomhle bude nějak skrytej problém.. Zkusil jsem kód upravit na ten lexikální uzávěr, ale nic to nedělá..

for (val in defval)
{
var itemname = val;
itemname = itemname.replace("_","-");
var checkelem = document.getElementById(itemname);

if (checkelem)
{
var checkeleminner = checkelem;
var start = +new Date();
var interval = setInterval(function(checkeleminner) // jestli jsem to dobře pochopil tak tohle by měl být lexikální uzávěr
{
  var delta = (new Date() - start) / 1000;
  if(delta > 1)
  {
    delta = 1;
    clearInterval(interval);
  }
var rgb1 = 52 + Math.floor(delta * 119);
var rgb2 = 65 + Math.floor(delta * 111);
var rgb3 = 128 + Math.floor(delta * 72);

checkeleminner.style.borderColor = "rgb(" + rgb1 + ", " + rgb2 + ", " + rgb3 + ")";  // tohle nedělá nic..
}, 13);


document.getElementById(itemname).style.color = "white";
$("#"+itemname).animate({
      color: "black"
    },1000);  // tohle funguje jak má

}
}



Chamurappi:
Mimochodem, pamatuješ, co jsem ti psal o tom, že diskuse není chat? Když něco vlepíš do příspěvku dodatečně, adresát si toho nemusí všimnout. Posílej příspěvky v kompletní podobě najednou.
Jo, ale to jsem doplnil asi do minuty, než si to stačil vůbec někdo přečíst..
_es
Profil
quatzael:
Nechce sa mi to podrobne skúmať, no možno bude chyba v tom, že delta rátaš v sekundách, no časovač máš zadaný v milisekundách.
quatzael
Profil
_es:
To by snad neměl být problém, ten skript normálně funguje (btw. psal ho Chamurappi), ale háže to chybu, že nezná ten element.. když tam zadám element normálně (ne jako proměnnou) tak to funguje..
_es
Profil
quatzael:
háže to chybu, že nezná ten element.
No tak ten element potom asi neexistuje. Nevytváraš ho nejako dynamicky, neskôr, než beží príslušný kód?
quatzael
Profil
_es:
proměnná itemname obsahuje hodnotu Id konkrétního elementu. Protože tím cyklem for (hned první řádek) projíždím celý objekt defval, někdy se stane, že itemname opravdu není Id pro žádný element.

Proto to taky testuju, jestli ten element existuje (řádek 7).
No a pokud existuje tak se provede jednak ta funkce s tím intervalem, kde to nefunguje (řádek 11 - 24), ale taky ta animace (27 - 30), která funguje jak má.

Problém je asi ten, že ta funkce s tím intervalem nějakou chvíli trvá a než se celá provede a dojde k tomu přiřazení vlastnosti k elementu (řádek 23), už běží další cyklus a hodnota tý proměnný itemname a tím pádem i objektu checkeleminner jiná..
_es
Profil
quatzael:
jestli jsem to dobře pochopil tak tohle by měl být lexikální uzávěr
Aha, to si pochopil zle, checkeleminner bude lokálna premenná (argument) anonymnej funkcie časovača a bude undefined. Prístup k inej premennej rovnakého mena „o úroveň vyššie“ preto nebude možný. Musíš definovať funkciu bez argumentov.
quatzael
Profil
_es:
To je hezký, ale i když dám ten argument pryč, tak to stejně nefunguje..
_es
Profil
quatzael:
Preštuduj si lepšie ten „lexikálny uzáver“ - kódy od Chamurappiho v tých príkladoch. Zhruba povedané, ten „lexikálny uzáver“ je, že si nejaký kód s definíciami vlastných premenných uzavrieš do:
(function(){kód})(argumenty)
Argumenty niekedy nie sú treba. A kód mimo ti nezmení hodnoty premenných vo funkcii ani hodnoty argumentov.
Do takého uzávera potrebuješ asi uzavrieť telo cyklu for..in.
_es
Profil
_
quatzael
Profil
_es:
Já opravdu nevím..
Zkusil jsem dát na konec funkce ten closure:

(řádek 24):
}(checkelem), 13);

Teď to začne jakoby barvit ten border, ale animace neproběhne až do konce. barva borderu zůstane jako na začátku animace..
Chamurappi
Profil
Reaguji na quatzaela:
Problém je asi ten, že ta funkce s tím intervalem nějakou chvíli trvá a než se celá provede […]
Ne, problém není, jak dlouho trvá, ale kdy se děje. Celý ten cyklus proběhne (a skončí) dřív, než se funkce nastavená přes setInterval poprvé spustí.

Zkusil jsem dát na konec funkce ten closure:
Closure je celá funkce, ne její konec. Když tu funkci uvnitř setIntervalu hned voláš, nediv se, že je jen jednou zavolaná (ona vrátí undefined, takže setInterval nedělá nic).

// jestli jsem to dobře pochopil tak tohle by měl být lexikální uzávěr
Nepochopil. Projdi si ty odkázané příklady ještě jednou.

Na tvém místě bych nejspíš dal cyklus dovnitř načasovaného funkce místo toho, abych nastavoval X separátních animací každou zvlášť. A nastavoval bych i background přes ní.
quatzael
Profil
Chamurappi:
Na tvém místě bych nejspíš dal cyklus dovnitř načasovaného funkce místo toho, abych nastavoval X separátních animací každou zvlášť.

Tak jsem to zkusil dát takhle dovnitř.. vůbec žádná změna chová se to úplně stejně:

var start = +new Date();
var interval = setInterval(function()
{ 

for (val in defval)
{

var itemname = val;
itemname = itemname.replace("_","-");
var checkelem = document.getElementById(itemname);

if (checkelem)
{
  var delta = (new Date() - start) / 1000;
  if(delta > 1)
  {
    delta = 1;
    clearInterval(interval);
  }

var rgb1 = 52 + Math.floor(delta * 119);
var rgb2 = 65 + Math.floor(delta * 111);
var rgb3 = 128 + Math.floor(delta * 72);

checkelem.style.borderColor = "rgb(" + rgb1 + ", " + rgb2 + ", " + rgb3 + ")";

document.getElementById(itemname).style.color = "white";
$("#"+itemname).animate({
      color: "black"
    },1000);

}
}
 
}(), 13);

Celý ten cyklus proběhne (a skončí) dřív, než se funkce nastavená přes setInterval poprvé spustí.
To nechápu jak to myslíš. Ta funkce se mi už normálně spouští, tenhle kód proběhne:

var rgb1 = 52 + Math.floor(delta * 119);
var rgb2 = 65 + Math.floor(delta * 111);
var rgb3 = 128 + Math.floor(delta * 72);
 
checkeleminner.style.borderColor = "rgb(" + rgb1 + ", " + rgb2 + ", " + rgb3 + ")"; 

Problém je ten, že ta hodnota proměnné delta zůstává nejspíš jaksi konstantní.. Barva se nastaví na výchozí hodnotu (delta = 0), ale pak už to k tý jedničce nepokračuje..

Nepochopil. Projdi si ty odkázané příklady ještě jednou.
Nechápu to z toho, nevím jak to líp pochopit.. Nevím ani proč je ta funkce setInterval definovaná v proměnný interval a co tam na konci dělá ta 13 ( 13);).. To se můžou časový parametry dávat libovolně k funkcím..?

A nastavoval bych i background přes ní.
Jakej background?
Chamurappi
Profil
Reaguji na quatzaela:
Ta funkce se mi už normálně spouští, tenhle kód proběhne
Jen jednou. Proč tu funkci hned voláš? Po tom jednom zavolání se ti řádek 2 vykoná stejně, jako kdybys napsal:
var interval = setInterval(undefined, 13)

Nevím ani proč je ta funkce setInterval definovaná v proměnný interval
Do proměnné interval se ukládá pořadové číslo načasovaného intervalu, pomocí něhož pak jde funkcí clearInterval opakování zastavit. Nezáleží, jaká je jeho konkrétní hodnota.

a co tam na konci dělá ta 13
Opakování po 13 milisekundách. Funkce proběhne cca 77× za sekundu v ideálním případě, reálně méněkrát (na 60 fps to nejspíš v průměru postačí).

To se můžou časový parametry dávat libovolně k funkcím..?
Je to druhý argument funkce setInterval.

Jakej background?
Pardon, myslel jsem color.
quatzael
Profil
Chamurappi:
Jen jednou. Proč tu funkci hned voláš?
To nechápu, kdy jí mám jako volat? To jí nemám dávat do toho argumentu k funkci setInterval?
quatzael
Profil
Chamurappi:
Prostě zkouším to sledovat co to dělá pomocí F12 a když si hodím breakpoint na řádek:

checkeleminner.style.borderColor = "rgb(" + rgb1 + ", " + rgb2 + ", " + rgb3 + ")";

Tak se mi to tam na něm furt zastavuje, tzn. že ten konkrétní skript probíhá a ne jen jednou. I ta hodnota delta (u barvy) se mění, jenom prostě nějak to nemění tu barvu.

Hodil jsem si tam i místo proměnný checkeleminner konkrétní neměnný elemement, (abych vyloučil možnost, že se ty elementy pořád mění) a prostě to furt nejede..


Chamurappi:
řekl bych, že tento příkaz se nikdy nevykoná: clearInterval(interval);

Ta funkce se pořád opakuje, ale prostě se tam nic nevykresluje.
Chamurappi
Profil
Reaguji na quatzaela:
To nechápu, kdy jí mám jako volat?
Nikdy, volá ji sám prohlížeč po uplynutém čase. Je to událost, podobně jako třeba onclick, akorát není závislá na uživatelské akci, ale na času.
A jinak viz rozdíl mezi voláním funkce a funkcí. Závorky () za funkcí ji vyvolají hned. Kdyby to byl lexikální uzávěr (tzn. funkce obalující příkazy jen proto, aby uchovávala jejich hodnoty), tak by okamžité zavolání dávalo smysl, v tomto případě nedává.

Tak se mi to tam na něm furt zastavuje, tzn. že ten konkrétní skript probíhá a ne jen jednou.
Máš ho teď v cyklu. Volá se tolikrát, kolikrát proběhne cyklus for (val in defval).

I ta hodnota delta (u barvy) se mění
Protože po každém spuštění po breakpointu je jiný čas a ty tu hodnotu počítáš tolikrát, kolikrát proběhne cyklus (zbytečně, jediná věc, která musí být v cyklu, je nastavení borderColor).
Máš obecně nějaké zkušenosti s programováním, nebo jen lepíš?
quatzael
Profil
Chamurappi:
Závorky () za funkcí ji vyvolají hned.
I když tu funkci klasicky definuju:

function functionname()
 {
//some code 
}
?

Přece nemůžu napsat jen:
function functionname
 {
//some code 
}

Navíc jsem to zkoušel dát ty závorky pryč, tedy takto:
setInterval(function
{ 

a nefunguje to vůbec! Syntaktická chyba předpokládám, protože se script v F12 vůbec neobjeví..

Tak jsem to teď trochu upravil, aby v tom for in byl čistě jen ten border a pořád je výsledek stejnej, proběhne to jednou a potom už ne. Ty závorky když dám pryč tak to nefunguje vůbec jak už jsem nahoře psal..

var idarray = new Array();
var itemname;

for (val in defval)
{
itemname = val;
itemname = itemname.replace("_","-");
sessionStorage[val] = defval[val];
var checkelem = document.getElementById(itemname);
if (checkelem)
idarray.push(checkelem);
}

var rgb1;
var rgb2;
var rgb3;

var interval = setInterval(function()
{ 
var start = +new Date();
var delta = (new Date() - start) / 1000;  
  if(delta > 1)
  {
    delta = 1;
    clearInterval(interval);
  }  

rgb1 = 52 + Math.floor(delta * 119);
rgb2 = 65 + Math.floor(delta * 111);
rgb3 = 128 + Math.floor(delta * 72);

for (idval in idarray)
{
idarray[idval].style.borderColor = "rgb(" + rgb1 + ", " + rgb2 + ", " + rgb3 + ")";
}

}(), 13);



Máš obecně nějaké zkušenosti s programováním, nebo jen lepíš?
Ne, už jsem to někde psal, že vůbec nejsem programátor. Rozhodl jsem se udělat trochu větší projekt a když jsem scháněl ajťáky tak z některých po nějaký době vypadlo, že to neumí (webový služby apod.) a jiní zkušení zase nechtěli do toho jít, protože to je až moc velkej a náročnej projekt..
Tak jsem se nakonec rozhodl, že to udělám sám, protože to je i lepší z toho důvodu, že si to můžu udělat přesně jak chci já a nemusím se s někým dohadovat donekonečna ohledně různých úprav atd..

Programování mi nepřipadá zase tak těžký, problém je totální absence kvalitních výukových materiálů. Když se chci dozvědět například jak vytvořit objekty a používat je, tak v učebnicích je hafo nesmyslnýho vyprávění, kde přirovnávají objekt k reálnýmu předmětu a popisují jeho funkce a vlastnosti (to co si dokáže bez toho hned představit každý i s nižším IQ), ale aby tam napsali, jak vypadá syntax, to ne..

Takže to tak různě lepím..


Chamurappi:
Teď mi došlo, že jsi asi myslel ty závorky za celou funkcí, tedy:

(poslední řádek)
}(), 13);

Ok, dal jsem to pryč, ale výsledek je pořád stejnej beze změny..


Chamurappi:
Tak už mi to konečně jede!!
Tohle už bylo fakt dlouhý..

Může za to tenhle řádek:
var start = +new Date();,
Když to bylo uvnitř tý funkce setInterval, tak se tam pořád nastavoval aktuální čas, proto byla delta pořád 0.

Mě se to zdálo divný už prve a zkoušel jsem to vyhazovat ven z tý funkce jako teď, ale nějak to nemělo žádný efekt, tak jsem to tam prve zase vrátil..


Takhle to už běhá:
var idarray = new Array();
var itemname;
 
for (val in defval)
{
itemname = val;
itemname = itemname.replace("_","-");
sessionStorage[val] = defval[val];
var checkelem = document.getElementById(itemname);
if (checkelem)
idarray.push(checkelem);
}
 
var rgb1;
var rgb2;
var rgb3;

var start = +new Date(); // tohle byl ten kámen úrazu..

var interval = setInterval(function()
{ 
var delta = (new Date() - start) / 1000;  
  if(delta > 1)
  {
    delta = 1;
    clearInterval(interval);
  }  
 
rgb1 = 52 + Math.floor(delta * 119);
rgb2 = 65 + Math.floor(delta * 111);
rgb3 = 128 + Math.floor(delta * 72);
 
for (idval in idarray)
{
idarray[idval].style.borderColor = "rgb(" + rgb1 + ", " + rgb2 + ", " + rgb3 + ")";
}
 
}, 13);
peta
Profil
rgb1 = 52 + Math.floor(delta * 119);
rgb2 = 65 + Math.floor(delta * 111);
rgb3 = 128 + Math.floor(delta * 72);
"rgb(" + rgb1 + ", " + rgb2 + ", " + rgb3 + ")"
?
rgb = [
52 + Math.floor(delta * 119),
65 + Math.floor(delta * 111),
128 + Math.floor(delta * 72)
];
alert(rgb[0]);
alert(rgb.join(", "));

"že to neumí" :)
"moc velkej a náročnej projekt" To je kazdy, zalezi na odmene. Kvalitni programovani je hodne narocne na cas a premysleni dopredu. Je to doslova hodinarska prace. Pokud neni dostatecne odmenena, je lepsi venovat cas mene narocnym vecem za vetsi penize a pak si uzit spousty volneho casu. Lide, kteri to nikdy nezkusili, to vubec netusi a mysli si, ze se to udela samo, protoze nejaky placal jim 5/100-tovar dodal rychle a vzhledove se to tvari hotove.

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:

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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