CSS prechody zablokované JavaScriptom
Snažím sa vytvoriť ukazovateľ načítania počas veľmi náročného obdobia JavaScriptu, kde sa vytvárajú a vypĺňajú dosť veľké 3D polia. Tento ukazovateľ načítania musí zostať prázdny, kým používateľ neklikne na tlačidlo.
Zmrazovanie nastáva bez ohľadu na to, či používam -webkit-transition (Táto aplikácia môže byť výlučne pre Chrome, kompatibilita s inými prehliadačmi v mojom prípade nie je potrebná).
Hľadajúc jednoduchosť som si postavil bar takto...
<div id="loader">
<div id="thumb">
</div>
</div>
... a potom som sa snažil zvýšiť túto hodnotu v rôznych fázach mojej hlavnej slučky for:
for(i = 0; i < 5 ; i++){
document.getElementById('thumb').style.width = i*25 + '%';
//More Code
}
Problém je, že všetko zamrzne, kým JavaScript neskončí. Našiel som podobnú otázku na Stack Overflow, Používanie CSS animácie, zatiaľ čo JavaScript počíta, a v komentároch som našiel a zvážil a/alebo vyskúšal nasledovné:
Weboví pracovníci
Nemyslím si, že to bude fungovať, pretože môj skript plní pole objektmi a konstruktormi obsahujúcimi funkcie, čo podľa tejto stránky nebude fungovať
jQuery
Nie je to možnosť, nemôžem vo svojej aplikácii používať externé knižnice - v každom prípade, importovať celú knižnicu len pre načítavací pruh sa zdá trochu prehnané...
Kľúčové snímky
Toto vyzeralo sľubne a vyskúšal som to, ale nakoniec to tiež zamrzne, takže žiadna radosť
timeOut()yPremýšľal som o tom, ale keďže účelom načítavacej lišty je znížiť frustráciu, zvýšenie čakacej doby sa zdá byť kontraproduktívne
Bol by som rád za akýkoľvek nárast baru v tejto fáze, aj keby nebol plynulý! Som si celkom istý, že toto je problém, ktorý postihol nielen mňa - možno niekto má zaujímavé riešenie?
P.S.: Zverejňujem to ako novú otázku, namiesto toho, aby som ju pridal k odkazovanej otázke, pretože konkrétne hľadám pomoc s JavaScriptom (nie jQuery) a uprednostnil by som, keby som to mohol získať pomocou prechodu (!=animácia) na šírke.
Odpoveď č. 1
Niektorí ľudia už spomenuli, že by ste mali používať časové limity. To je vhodný prístup, pretože to dá prehliadaču čas „dýchať“ a vykresliť váš pokrokový panel počas úlohy.
Musíte rozdeliť svoj kód, aby pracoval asynchrónne. Povedzme, že momentálne máte niečo takéto:
function doAllTheWork() {
for(var i = 0; i < reallyBigNumberOfIterations; i++) {
processorIntensiveTask(i);
}
}
Potom to musíte premeniť na niečo takéto:
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šimnite si výraz (Date.now() - startTime) < 30. To znamená, že slučka vykoná toľko, koľko môže, počas 30 milisekúnd. Toto číslo môžete zväčšiť, ale čokoľvek nad 100 ms (v podstate 10 snímok za sekundu) bude z pohľadu používateľa začínať pôsobiť pomaly.
Môže byť pravda, že celková úloha bude trvať o niečo dlhšie pri použití tohto prístupu v porovnaní so synchronnou verziou. Avšak z pohľadu používateľa je lepšie mať indikáciu, že niečo sa deje, než čakať neobmedzene, zatiaľ čo sa zdá, že sa nič nedeje - aj keď je táto časť čakania kratšia.
Odpoveď č. 2
Skúsili ste ísť ešte jednoduchšie a vytvoriť funkciu, povedzme:
Pseudonym :
Function increment_bar(amount = 10)
{
document.getElementById('thumb').style.width = i*amount + '%';
}
Potom odkiaľkoľvek, kde vykonávate svoju spracovateľskú prácu, jednoducho volajte túto funkciu každých x sekúnd alebo kedykoľvek, keď dosiahnete určitý bod v spracovaní (povedzme 10-20 % dokončenia?)
Pseudonym :
{
Doing_work_here;
increment_bar(25);
LOOP
}
