Autor Zpráva
fadeIn
Profil *
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
fadeIn:
Cannot read property 'style' of null"
Element sa takým id neexistuje.
Radek9
Profil
fadeIn:
Když voláš ten setTimeout, tak tam nepředáváš ani to id, ani čas.
window.setTimeout(function () { fadeIn(id, time); }, time);
Chamurappi
Profil
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
Suta:
Není to tak zcela pravda, setTimeout je v cyklu přesnější než setInterval.
Čo presne v tej vete znamená „presnejší“?
Suta
Profil
_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
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
Suta:
Jedna z cest je pak použití dvou nezávislých časovačů
Zbytečně složité. Viděl jsi [#4]?
Suta
Profil
Keeehi:
Viděl a přečetl, souhlasím s tebou.
Chamurappi
Profil
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 setIntervalem 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
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
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.

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: