Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 20.12.2017, 15:48
Кандидат Javascript-наук
Отправить личное сообщение для jaroslav.tavgen Посмотреть профиль Найти все сообщения от jaroslav.tavgen
 
Регистрация: 18.09.2014
Сообщений: 128

Как заставить 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

Я думал, что мой вопрос настолько базовый, что мне немедленно дадут ссылку на матчасть. Вместо этого они пишут, что мой вопрос - дубликат вопроса "Давай покрасим холодильник в чёрный цвет" и предлагают кучу решений, которые НЕ РАБОТАЮТ.
Ответить с цитированием
  #2 (permalink)  
Старый 20.12.2017, 16:28
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

В firefox проблемы нет. Closed: Worksforme.
Пишите письма в багтреккер хрома.)

Вообще причина, очевидно, в том, что вызов alert почему-то не считается хромом достаточной причиной для перерисовки. В обычном случае действительно не имеет смыла перерисовывать страницу после каждого шага цикла, т.к. цикл неделимая операция, но по логике вещей alert или какой-нить yield должен таки тригерить это действие.
Принудительный requestAnimationFrame, конечно порешает проблему, но, имхо, данная ситуация если не баг то хреновый код. (Полагаю причина в принципиальном презрении к самому alert )
__________________
29375, 35

Последний раз редактировалось Aetae, 20.12.2017 в 16:41.
Ответить с цитированием
  #3 (permalink)  
Старый 20.12.2017, 16:46
Кандидат Javascript-наук
Отправить личное сообщение для jaroslav.tavgen Посмотреть профиль Найти все сообщения от jaroslav.tavgen
 
Регистрация: 18.09.2014
Сообщений: 128

Сообщение от Aetae Посмотреть сообщение
В firefox проблемы нет. Closed: Worksforme.
Пишите письма в багтреккер хрома.)

Вообще причина, очевидно, в том, что вызов alert почему-то не считается хромом достаточной причиной для перерисовки. В обычном случае действительно не имеет смыла перерисовывать страницу после каждого шага цикла, т.к. цикл неделимая операция, но по логике вещей alert или какой-нить yield должен таки тригерить это действие.
Принудительный requestAnimationFrame, конечно порешает проблему, но, имхо, данная ситуация если не баг то хреновый код. (Полагаю причина в принципиальном презрении к самому alert )
У меня в Firefox работает абсолютно так же.
Ответить с цитированием
  #4 (permalink)  
Старый 20.12.2017, 16:54
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

Сообщение от jaroslav.tavgen Посмотреть сообщение
У меня в Firefox работает абсолютно так же.
Абсолютно также это как?)
http://ajitae.tk/test/2.html
FF57.0.2 64bit win7, win8 - всё как надо.
__________________
29375, 35
Ответить с цитированием
  #5 (permalink)  
Старый 20.12.2017, 17:04
Кандидат Javascript-наук
Отправить личное сообщение для jaroslav.tavgen Посмотреть профиль Найти все сообщения от jaroslav.tavgen
 
Регистрация: 18.09.2014
Сообщений: 128

Сообщение от Aetae Посмотреть сообщение
Абсолютно также это как?)
http://ajitae.tk/test/2.html
FF57.0.2 64bit win7, win8 - всё как надо.
Да, прошу прощения, это я перепутал. Всё правильно. Спасибо большое, за ответ! Я посмотрю, как моя программа (не эта, а настоящая) работает в Firefox, и тогда возможно поподробнее напишу
Ответить с цитированием
  #6 (permalink)  
Старый 20.12.2017, 17:32
Кандидат Javascript-наук
Отправить личное сообщение для jaroslav.tavgen Посмотреть профиль Найти все сообщения от jaroslav.tavgen
 
Регистрация: 18.09.2014
Сообщений: 128

Всё ясно, в моей программе была ошибка совсем другого плана.

Aetae, спасибо большое!
Ответить с цитированием
  #7 (permalink)  
Старый 20.12.2017, 17:53
Кандидат Javascript-наук
Отправить личное сообщение для jaroslav.tavgen Посмотреть профиль Найти все сообщения от jaroslav.tavgen
 
Регистрация: 18.09.2014
Сообщений: 128

И все-таки вопрос у меня есть.

document.body.innerHTML = "";
for (var i=0;i<1000000;i++){
    document.body.innerHTML += "a";
}

Пока цикл не отработает миллион раз, на экран ничего не будет выведено.

А как сделать так, чтобы он добавлял по одной буковке за раз?
Ответить с цитированием
  #8 (permalink)  
Старый 20.12.2017, 18:51
Аватар для Белый шум
Профессор
Отправить личное сообщение для Белый шум Посмотреть профиль Найти все сообщения от Белый шум
 
Регистрация: 19.01.2012
Сообщений: 505

<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>

Последний раз редактировалось Белый шум, 20.12.2017 в 18:54.
Ответить с цитированием
  #9 (permalink)  
Старый 20.12.2017, 19:00
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,138

Сообщение от jaroslav.tavgen Посмотреть сообщение
А как сделать так, чтобы он добавлял по одной буковке за раз?
В цикле практически ни как.

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>

Последний раз редактировалось MallSerg, 20.12.2017 в 19:05.
Ответить с цитированием
  #10 (permalink)  
Старый 20.12.2017, 22:03
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

Добавлю для ясности: однопоточность означает, что пока поток занят циклом, он физически не может ничего рисовать. Цикл - единичный неделимый блок. Чтобы гарантировано, сразу по возможности(fps), результат появлялся на экране - придумали requestAnimationFrame, но за отсутствием(старый ослик) и setTimeout пойдёт.
__________________
29375, 35

Последний раз редактировалось Aetae, 20.12.2017 в 22:06.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как на JavaScript подгрузить JavaScript? Pug-dog&Elephant Opera, Safari и др. 2 18.09.2011 15:43
как заставить работать часы d4a1 Общие вопросы Javascript 2 04.08.2011 21:29
Как заставить работать скрипт Highlight wfire jQuery 2 30.05.2011 10:22
Как можно совместить 2 "одинаковые javascript но разные внутри" в одну страницу?..ато rashid86 Элементы интерфейса 2 25.04.2011 22:49
Как заставить работать .change для <select> где-то, кроме оперы? InviS jQuery 3 09.10.2010 23:02