Autor | Zpráva | ||
---|---|---|---|
fadeIn Profil * |
#1 · Zasláno: 21. 8. 2012, 14:23:16
Dobrý den,
nedaří si mi napsat v JS funkci fadeIn z Jquery. Konzole hlásí "Uncaught TypeError: Cannot read property 'style' of null". Předem děkuju za odpověď. var i = 0; function fadeIn(id,time){ if (i==9){ document.getElementById(id).style.opacity = 1; return; } else { i++; document.getElementById(id).style.opacity = 0+"."+i; window.setTimeout(fadeIn,time); } } |
||
_es Profil |
#2 · Zasláno: 21. 8. 2012, 14:30:42
fadeIn:
„Cannot read property 'style' of null"“ Element sa takým id neexistuje.
|
||
Radek9 Profil |
#3 · Zasláno: 21. 8. 2012, 14:30:56
fadeIn:
Když voláš ten setTimeout, tak tam nepředáváš ani to id, ani čas. window.setTimeout(function () { fadeIn(id, time); }, time); |
||
Chamurappi Profil |
#4 · Zasláno: 21. 8. 2012, 14:40:29
Reaguji na fadeIna:
Na animace se víc hodí setInterval , ideálně i s přeměřováním času. Napsal bych to nějak takhle:
function fadeIn(id, time) { var element = document.getElementById(id); function update(delta) { element.style.opacity = delta; } var start = new Date().getTime(); var interval = setInterval(function() { var delta = (new Date().getTime() - start) / time; if(delta > 1) { clearInterval(interval); delta = 1; } update(delta); }, 13); update(0); } |
||
Suta Profil |
Chamurappi:
Není to tak zcela pravda, setTimeout je v cyklu přesnější než setInterval. Záleží však, jak přesné "pravidelnosti" (tj. minimalizace odchylek, resp. posunutí počátku každého intervalu, které u setIntervalu nastávají) je potřeba. Na druhou stranu v aktuálních verzích prohlížečů (včetně IE) už rozdíl mezi použitím setIntervalu a setTimeoutu v cyklu není tolik markantní jako ještě před dvěma lety. |
||
YOYO Profil |
A pokud máš fadeIn, možná budeš chtít i fadeOut, pak je asi lepší, než psát dvě téměř stejné funkce, to smrsknout do jednoho objektu, třeba nějak takhle (možná to bude trochu míň přesné, než chamurappiho řešení):
var fade = new function(){ //Singleton var S = 17; // čas mezi jednotlivými kroky function anim(id,ms,direction){ var element = document.getElementById(id); ms = ms || 500; // výchozí trvání animace if(!element) return; var opacity = (direction==1?0:1); var interval = setInterval(step,S) function step(){ element.style.opacity = opacity = opacity+(S/ms)*direction; if(opacity<0 || opacity>1) clearInterval(interval); } } this.out = function(id,ms){ anim(id,ms,-1); } this.in = function(id,ms){ anim(id,ms,+1); } }() //příklad použití: window.onload = function(){ fade.out("id",1000); setTimeout(function(){fade.in("id",2000)},2000) } |
||
_es Profil |
#7 · Zasláno: 21. 8. 2012, 16:12:03
Suta:
„Není to tak zcela pravda, setTimeout je v cyklu přesnější než setInterval.“ Čo presne v tej vete znamená „presnejší“? |
||
Suta Profil |
#8 · Zasláno: 22. 8. 2012, 12:57:30
_es:
SetInterval způsobuje výchylky (posunutí) začátku každého nového intervalu (a tím posunutí všech následujících) v případě, že musí vlákno javascriptu v daném momentě provést jinou operaci (javascript až na výjimky nepracuje asynchronně). SetTimeout v cyklu tyto odchylky eliminuje, resp. lépe řečeno minimalizuje. Nedokážu teď přesně říci jak to funguje technicky, nicméně je na netu několik testů, které moje tvrzení dokazují. Před třemi lety jsem dělal také animované cykly, včetně metod fadeIn, fadeOut s cílem dosáhnout co největší plynulosti. Také jsem používal setInterval a ať jsem se snažil jakkoliv, animace plynulé nebyly. Rapidně v IE, ale kromě Chrome kdekoliv. Po přečtení několika článků na zmíněné téma "plynulosti" jsem podle rad zaměnil za setTimeout v cyklu a problém byl vyřešen. |
||
Joker Profil |
#9 · Zasláno: 22. 8. 2012, 13:43:01
Suta:
Určitě to je takhle? Nezkoušel jsem to, ale z logiky věci bych řekl, že by to mělo být přesně obráceně: Opakované volání setTimeout přece musí způsobit, že každý interval se prodlouží o dobu mezi spuštěním funkce a zavoláním setTimeout, resp. pokud je setTimeout na konci funkce, tak o dobu potřebnou k vykonání celé funkce. |
||
Suta Profil |
Joker:
Jedna věc stojí za zmínku, a to, že setTimeout čeká na funkci až do konce provádění. Čeká x ms a poté funkci zavolá znovu. Na druhé straně setInterval se pokusí(!) provést funkci každých x ms bez ohledu na to, kdy byla funkce volána nebo jak dlouho se má funkce provádět. Pěkný článek je zde: http://ejohn.org/blog/how-javascript-timers-work/ Nicméně pokud chce člověk docílit té nejlepší plynulosti scriptováním v javascriptu, pak nejlepší cesta je používat "snímkování", tj.: Namísto logiky "odkud kam a kolikrát" použít logiku "finální stav a za jak dlouho". Jedna z cest je pak použití dvou nezávislých časovačů, kdy druhý (pomocný) zjišťuje, zda-li se hlavní časovač neopozdil a v případě že ano, pak některé kroky animace vypustí (přeskočí). |
||
Keeehi Profil |
#11 · Zasláno: 22. 8. 2012, 14:32:35
|
||
Suta Profil |
#12 · Zasláno: 22. 8. 2012, 14:43:29
Keeehi:
Viděl a přečetl, souhlasím s tebou. |
||
Chamurappi Profil |
#13 · Zasláno: 22. 8. 2012, 15:08:55
Reaguji na Sutu:
„setInterval se pokusí(!) provést funkci každých x ms bez ohledu na to, kdy byla funkce volána“ Takže když animaci napumpuji co nejrychlejším možným intervalem, prohlížeč provede co nejvíc animačních kroků, co zvládne. Pokud se mu to nehodí, krok vynechá. Mám rozpracovanou jednu hru, kde jsem se pokoušel o kompenzace setTimeout ů i s předvídáním náročnosti některých kroků, bylo to zbytečně složité a režie kolem toho sama o sobě trošku zpomalovala. Nakonec jsem to nahradil setInterval em a vše je krásně jednoduché a šlape to stejně…
„použít logiku "finální stav a za jak dlouho"“ Také jsem si tuto logiku oblíbil. |
||
Suta Profil |
Chamurappi:
„Takže když animaci napumpuji co nejrychlejším možným intervalem, prohlížeč provede co nejvíc animačních kroků, co zvládne.“ Teoreticky ano. Praxe se bohužel v jednotlivých prohlížečích skutečně liší. Logika vynechávání toho, co prohlížeč nezvládne v případě setIntervalu a čas, kdy skutečně provede to, co následuje po vynechaném kroku jsou věci často stěží pochopitelné. „Nakonec jsem to nahradil setIntervalem a vše je krásně jednoduché a šlape to stejně…“ Je to možné. Můžeš napsat, v jakých verzích prohlížečů to už nešlape? Po osobních zkušenostech s pokusy naprogramovat v javascriptu hry (vynechám-li textovky) jsem dospěl k názoru, že je to jedna z velmi dobrých cest naučit se v javascriptu lépe programovat. Ohledně praktické využitelnosti takovýchto her (vezmu-li v potaz hry spojené s potřebou využívat rychlou časovou posloupnost v cyklu) jsem však spíše spektický, doporučuji přejít na Canvas. |
||
Chamurappi Profil |
#15 · Zasláno: 22. 8. 2012, 17:59:27
Reaguji na Sutu:
„Praxe se bohužel v jednotlivých prohlížečích skutečně liší.“ Nevšiml jsem si. Byla by ukázka? Nebo odkaz na nějaké povídání? „Můžeš napsat, v jakých verzích prohlížečů to už nešlape?“ Nestanovil jsem si žádnou konkrétní laťku. V Exploreru 6 to momentálně funguje, akorát je to méně svižné při velkém okně. „doporučuji přejít na Canvas“ Používám v hojné míře i <canvas> — pokud ho prohlížeč podporuje.
|
||
Suta Profil |
Chamurappi:
„V Exploreru 6 to momentálně funguje“ Uf!, tak to klobouk dolů. Rád bych viděl onen script. Nicméně ti samozřejmě věřím i bez jeho uveřejnění. „Nevšiml jsem si. Byla by ukázka? Nebo odkaz na nějaké povídání?“ To už bude složitější, problém jsem řešil před dvěma a půl roky. Zkusil jsem ale pohledat ve svých starých kódech a jednu ukázku jsem našel. Kód je strašná divočina, dnes se za něj stydím, bylo to v začátcích mého scriptování. Nicméně vím, že konkrétně u tohoto pokusu jsem tehdy neplynulost střel či kuličky (hlavně v IE) vyřešil záměnou setIntervalu za setTímeout. Díval jsem se, že v kódu je setInterval, při kliknutí několikrát za sebou na žlutý obdélník by ve starších verzích IE měla být vidět neplynulost střel. Ukázka Jinak jsem to tehdy řešil zde. Plynulost operací v javascriptu |
||
Chamurappi Profil |
#17 · Zasláno: 23. 8. 2012, 12:50:28
Reaguji na Sutu:
Odkázaná ukázka zřejmě nefunguje správně v žádném prohlížeči, zapomněls tam přilinkovat js_knihovna.js . Ten jediný pohyb tečky, co vidím, mi připadá stejně plynulý i ve starém Exploreru na starším počítači.
„Jinak jsem to tehdy řešil zde.“ Tehdy jsi se zjevně rozhodnul pro setInterval .
„Uf!, tak to klobouk dolů. Rád bych viděl onen script.“ Ona v tom žádná velká věda není, obrázky a pozicování fungují ve všech prohlížečích cca stejně. Jediné, co jsem speciálně kvůli šestce ošetřoval, byl alfakanál PNG, na to stačila jedna stručná podmínka. Později jsem AlphaImageLoader stejně použil i v sedmičce a osmičce, protože je trošku rychlejší než background a při transformaci filtrem Matrix se nerozbíjí průhlednost.
|
||
Časová prodleva: 12 let
|
0