непонятное поведение InnerHTML
Дело вот в чем. Есть конструктор Tank, который в зависимоит от переданного параметра name создает два вида танков (Т34 и Тигр). Тигр выступает в качестве мишени, который Т34 расстреливает. При нажатии на кнопку "Атаковать" запускается цикл while, в котором пока Тигр не будет уничтожен танк Т34 ведет по нему огонь. Очки прочности Тигра отображаются в элементе div, который расположен рядом с картинкой Тигра. Вот функция атаки танка
Tank.prototype.attack = function(target) { if (target == Tiger){ target.hp = target.hp - this.damage; tooltipElemTiger.innerHTML = target.hp; alert(this.name + " атаковал " + target.name); alert("Очков прочности " + target.name + target.hp + " единиц"); if (target.hp <= 0) this.destroyed(target);} }; По идее после каждого выстрела параметр InnerHTML должен обновляться и отображать количество оставшихся единиц прочности танка. НО он обновляется только ПОСЛЕ того, как Тигр уничтожен, а не после каждого выстрела. Сломал всю голову но так и непойму проблемы. Если в функции battle убрать цикл и просто несколько раз прописать функцию атаки, то всё работает корректно (див обновляет оставшуюся прочность после каждого выстрела). Значит проблема именно в циклическом выполнении функции. Вот ссылка на кодпен, чтобы наглядно всё было видно. Не обращайте внимания, что не всё ровно, пока интересует только функциональная часть. https://codepen.io/Sergeev2/pen/qxLXzB |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> document.body.style.backgroundColor = "red"; alert(); </script> </body> </html> Известная проблема |
Вместо while рекурсивный setTimeout и все заработает
|
А с чем связана такая непонятная работа скрипта? По идее команды должны выполняться одна за другой, а не как попало
|
Цитата:
|
Самовар,
Это не какая то ошибка языка, интерпретатор так настроен у хрома и браузеров сделанных на его основе. |
в примере Жоника, сперва вывелся алерт, а потом изменился цвет. Как-то не очень одна за другой, если я правильно понял
|
Цитата:
Это хорошо видно на примере j0hnik. Тебе нужно все изменения страницы "уводить" в другой поток. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> document.body.style.backgroundColor = "red"; setTimeout(function(){ alert(); },1); </script> </body> </html> |
Цитата:
|
про криво работающт экплорер наслышан, но с гуглом думал всё нормально. То есть и для гугла нужно применять специфичекие приемы?
|
ладно, спасибо за помощь, хоть какое-то направление мысли получил
|
Самовар,
просто не используйте Alert, пора переходить на console.log() :) |
Цитата:
|
Цитата:
Небольшой пример <div id="AA">1234</div> <script> var a = document.all["AA"]; var i = 0; while ( i++ < 100000){ a.innerHTML = i; } </script> Ни один браузер не будет отрисовывать этот див сто тысяч раз. по тому что это в миллионы раз медленнее чем просто увеличение переменой (свойства) на единицу. Просто у некоторых браузеров возникает желание отрисовать изменения раз а пол секунды. Раньше в стандарте было указано что рисовать нельзя во время выполнения скриптов в новом этот пункт убрали. Можешь попробовать сменить доктайп на HTML 4.01. тогда во время работы JS браузер не должен рендерить страницу. похожая тема https://javascript.ru/forum/misc/718...tml#post473386 |
большая просьба. Помогите мой цикл while переделать в рекурснивный setTimeout. Единственное, чего смог добиться, это бесконечно работающая рекурсия (то есть бесконечный самовызов себя), потому что в результате моей работы в this вместо Т34 попадает Windows, в результате чего все операции с this возвращают NaN. И прочность моего тигренка всегда NaN (что логично, потому что атака Windows тоже NaN)
Tank.prototype.attack = function(target) { if (target == Tiger) { setTimeout(function() { target.hp = target.hp - this.damage; tooltipElemTiger.innerHTML = target.hp; alert(this.name + " атаковал " + target.name); alert("Очков прочности " + target.name + target.hp + " единиц"); if (target.hp <= 0) this.destroyed(target); }, 5000); } }; function battle() { setTimeout(T34.attack(Tiger), 1000); } |
|
блин, спасибо, вы реально умные)
|
Часовой пояс GMT +3, время: 23:48. |