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()yPř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
}
