Как заставить javascript работать нормально?
document.body.innerHTML = ""; for(var i=0;i<3;i++){ document.body.innerHTML+="Hi! "; alert(); } Как я хочу, чтобы работала программа: 1. Очистила элемент body. 2. Написала "Hi! " 3. Выдала alert. 4. После закрытия alert ещё раз написала "Hi !". 5. Выдала alert. 4. После закрытия alert ещё раз написала "Hi !". 5. Выдала alert. Как она работает вместо этого, вы видите. Как сделать так, чтобы программа работала так как я хочу (и как она работала бы в PHP, Java, C и т.д.)? Очень удивил stackoverflow: https://stackoverflow.com/questions/...78675_47905481 Я думал, что мой вопрос настолько базовый, что мне немедленно дадут ссылку на матчасть. Вместо этого они пишут, что мой вопрос - дубликат вопроса "Давай покрасим холодильник в чёрный цвет" и предлагают кучу решений, которые НЕ РАБОТАЮТ. |
В firefox проблемы нет. Closed: Worksforme. :)
Пишите письма в багтреккер хрома.) Вообще причина, очевидно, в том, что вызов alert почему-то не считается хромом достаточной причиной для перерисовки. В обычном случае действительно не имеет смыла перерисовывать страницу после каждого шага цикла, т.к. цикл неделимая операция, но по логике вещей alert или какой-нить yield должен таки тригерить это действие. Принудительный requestAnimationFrame, конечно порешает проблему, но, имхо, данная ситуация если не баг то хреновый код. (Полагаю причина в принципиальном презрении к самому alert:) ) |
Цитата:
|
Цитата:
http://ajitae.tk/test/2.html FF57.0.2 64bit win7, win8 - всё как надо. |
Цитата:
|
Всё ясно, в моей программе была ошибка совсем другого плана.
Aetae, спасибо большое! |
И все-таки вопрос у меня есть.
document.body.innerHTML = ""; for (var i=0;i<1000000;i++){ document.body.innerHTML += "a"; } Пока цикл не отработает миллион раз, на экран ничего не будет выведено. А как сделать так, чтобы он добавлял по одной буковке за раз? |
<html><body></body></html> <script> document.body.innerHTML = ""; var end=500; (function tick(i) { document.body.innerHTML += "a"; if(i<end) setTimeout(tick.bind(null, i+1), 1); })(0); </script> |
Цитата:
JS строго однопоточен. т.е. использовать несколько потоков в одном контексте исполнения невозможно. в JS невозможно ограничить область видимости одного потока от области видимости другого потока (глобальный объект, цепочка прототипов) доступны всем и всегда. Изменения данных в одном потоке сделают непредсказуемым результат работы в другом потоке. самый простой способ обойти блокировку других задач (рендеринга) пока работает долгий код это разбить задачу вызовами асинхронной функции setTimeout (задача,0) т.е. запустить/продолжить задачу после того как браузер сделает все ожидающие операции. небольшой пример <body><script> function repeat (fun,size){ +function asd (){ fun(); if (size % 110 == 0) document.body.innerHTML += "<br>"; if ( --size > 0) setTimeout (asd,0); }(); } function idiotizm (){ document.body.innerHTML += "a"; } repeat (idiotizm , 6000); </script> |
Добавлю для ясности: однопоточность означает, что пока поток занят циклом, он физически не может ничего рисовать. Цикл - единичный неделимый блок. Чтобы гарантировано, сразу по возможности(fps), результат появлялся на экране - придумали requestAnimationFrame, но за отсутствием(старый ослик) и setTimeout пойдёт.
|
Часовой пояс GMT +3, время: 14:32. |