Vyhledávání na webu

Přechody CSS blokované JavaScriptem


Snažím se vytvořit načítací lištu během velmi náročného období JavaScriptu, kdy jsou tvořena a plněna docela těžká 3D pole. Tato načítací lišta musí zůstat prázdná, dokud uživatel neklikne na tlačítko.

Zmrazení nastává ať už používám -webkit-transition, nebo ne (Tato aplikace může být výhradně pro Chrome, napříč prohlížeči není v mém případě nutné).

Hledaje jednoduchost, postavil jsem svůj bar takto...

<div id="loader">
    <div id="thumb">
    </div>
</div>

... a pak jsem se snažil zvýšit tu hranici v různých fázích mého hlavního for cyklu:

for(i = 0; i < 5 ; i++){
    document.getElementById('thumb').style.width = i*25 + '%';
    //More Code
}

Problém je v tom, že se všechno zastaví, dokud JavaScript neskončí. Našel jsem podobnou otázku na Stack Overflow, Použití CSS animace, zatímco JavaScript provádí výpočty, a v komentářích jsem našel, zvážil a/nebo vyzkoušel následující:

  • Weboví pracovníci

    Nemyslím si, že to bude fungovat, protože můj skript naplňuje pole objekty a konstruktory obsahujícími funkce, což podle tohoto webu nebude fungovat

  • jQuery

    Není to možné, nemohu ve své aplikaci používat externí knihovny - v každém případě se importování celé knihovny jen kvůli načítacímu pruhu zdá být trochu přehnané...

  • Klíčové snímky

    To vypadalo slibně a zkusil jsem to, ale nakonec se to také zasekne, takže žádná radost

  • timeOut()y

    Přemýšlel jsem o tom, ale protože smyslem načítacího pruhu je snížit frustraci, zdá se, že zvýšení čekací doby je kontraproduktivní.

Byl bych rád za jakékoli zvýšení pruhu v této fázi, i kdyby nebylo plynulé! Jsem si docela jistý, že tento problém postihl víc než jen mě - možná má někdo zajímavé řešení?

P.S.: Toto zveřejňuji jako novou otázku, spíše než abych přidával k odkázané otázce, protože konkrétně hledám pomoc s JavaScriptem (ne jQuery) a upřednostnil bych, pokud bych to mohl získat pomocí přechodu (!= animace) na šířce.

Odpověď č. 1

Někteří lidé již zmínili, že byste měli používat časové limity. To je vhodný přístup, protože to dá prohlížeči čas na to, aby si „oddechl“ a vykreslil váš průběhový pruh během úkolu.

Musíte svůj kód rozdělit, aby fungoval asynchronně. Řekněme, že momentálně máte něco takového:

function doAllTheWork() {
  for(var i = 0; i < reallyBigNumberOfIterations; i++) {
    processorIntensiveTask(i);
  }
}

Pak to musíte převést na něco takového:

var i = 0;
function doSomeWork() {
  var startTime = Date.now();
  while(i < reallyBigNumberOfIterations && (Date.now() - startTime) < 30) {
    processorIntensiveTask(i);
    i++;
  }

  if(i < reallyBigNumberOfIterations) {
    // Here you update the progress bar
    incrementBar(i / reallyBigNumberOfIterations);

    // Schedule a timeout to continue working on the heavy task
    setTimeout(doSomeWork, 50);
  }
  else {
    taskFinished();
  }
}

function incrementBar(fraction) {
  console.log(Math.round(fraction * 100) + ' percent done');
}

function taskFinished() { console.log('Done!'); }

doSomeWork();

Všimněte si výrazu (Date.now() - startTime) < 30. To znamená, že smyčka zvládne co nejvíce práce během 30 milisekund. Toto číslo můžete zvětšit, ale cokoli nad 100 ms (v podstatě 10 snímků za sekundu) už začne z pohledu uživatele působit pomalu.

Může být pravda, že celkový úkol bude trvat poněkud déle při použití tohoto přístupu ve srovnání se synchronní verzí. Z pohledu uživatele je však lepší mít indikaci, že něco se děje, než čekat donekonečna, zatímco se zdá, že nic se neděje - i když je doba čekání v druhém případě kratší.

Odpověď č. 2

Zkoušel jste jít ještě jednodušeji a vytvořit funkci, řekněme:

Přezdívka :

Function increment_bar(amount = 10)
{
 document.getElementById('thumb').style.width = i*amount + '%';
}

Pak odkudkoli, odkud provádíte svou zpracovatelskou práci, stačí volat tuto funkci každých x sekund nebo kdykoli dosáhnete určitého bodu ve zpracování (řekněme 10-20% dokončení?)

Přezdívka :

{
    Doing_work_here;
    increment_bar(25);
    LOOP
}