CSS-анимация останавливается при запуске функции javascript

Скажем, у меня есть эта функция javascript:

   function pauseComp(ms) {
     var date = new Date();
     var curDate = null;
     do { curDate = new Date(); }
     while(curDate-date < ms);
    }

и анимация css3 (например, <i class="icon-spinner icon-spin"></i> из нового font-awesome 3). Когда я запускаю функцию javascript выше, она останавливает счетчик во время работы функции. Посмотрите, о чем я говорю здесь. По сути, javascript останавливает анимацию css, и мне интересно, почему, или если кто-нибудь еще заметил это/нашел обходной путь. Я пытался поместить его в setTimeout(fn,0), где fn — это длинный процесс, но потом понял, почему это тоже не сработает (js не является многопоточным). Кто-нибудь видел, как это происходит?

Обновление: интересно, похоже, что это не такая большая проблема в Safari, хотя взаимодействие с интерфейсом браузера все еще страдает.


person Christian Bankester    schedule 16.01.2013    source источник
comment
Вам нужно будет разбить ваш длинный код на куски, чтобы все остальное продолжалось.   -  person Lee Taylor    schedule 17.01.2013
comment
Да, хотя я знаю, что это исправит это, это не жизнеспособное решение для функций, к которым я пытаюсь применить это. Функции не разбиваются на более мелкие фрагменты. Я действительно проверяю, есть ли у кого-нибудь решение точно указанной выше проблемы, которую также нельзя разбить.   -  person Christian Bankester    schedule 17.01.2013


Ответы (1)


Страница браузера является однопоточной. Обновление пользовательского интерфейса происходит в том же потоке, что и ваша программа javascript. Это также означает, что любая анимация не будет рисовать новые кадры во время выполнения кода Javascript. Как правило, в этом нет ничего страшного, потому что большая часть кода JS выполняется очень быстро, быстрее, чем один кадр анимации.

Поэтому лучший совет прост: не делайте этого. Не блокируйте JS-движок так долго. Придумайте более чистый способ сделать это.


Однако, если вам нужно, есть способ. Вы можете создать дополнительный поток через HTML5 Web Workers API. Это не поддерживается в старых браузерах, но позволит вам запускать какой-то продолжительный код, загружающий ЦП, вне основной веб-страницы и в своем собственном потоке, а затем отправлять результат на вашу страницу, когда это будет сделано.

person Alex Wayne    schedule 16.01.2013
comment
Да, я видел веб-воркеров. Знаете ли вы, есть ли у веб-воркеров доступ к DOM? Потому что мой длительный процесс — это все обновления DOM, происходящие в jQuery, и это то, что медленно. - person Christian Bankester; 17.01.2013
comment
Веб-работники @ChristianBankester не могут получить доступ к DOM. Вам придется использовать setTimeout. - person bfavaretto; 17.01.2013
comment
Ах, я пытался использовать setTimeout, но это не сработало. Посмотрите этот обновленный jsfiddle: jsfiddle.net/JU4St/2 - person Christian Bankester; 17.01.2013
comment
Кроме того, я понимаю, что это природа javascript, однопоточная и все такое. Просто интересно, есть ли есть исправление, которое выполнит то, что я ищу. - person Christian Bankester; 17.01.2013
comment
Сочетание setTimeout с вашим pauseComp не сработает. Вы должны разделить свою трудоемкую операцию на куски и вызывать фрагмент за раз, используя setTimeout. - person bfavaretto; 17.01.2013
comment
setTimeout не создает новый поток. Он просто планирует вызов функции в основном потоке позже. При вызове он все равно будет блокироваться. Если все, что вы хотите сделать, это запланировать некоторые вызовы, которые будут вызваны позже, и этот код работает быстро, все, что вам нужно, это setTimeout(someFn, 3000). Вам понадобится рабочий поток только в том случае, если вы выполняете какие-то очень интенсивные вычисления ЦП. - person Alex Wayne; 17.01.2013