body.innerhtml - что за чертовщина?
Первый раз пишу на форум - может не в тот раздел... но решил вот, что сюда мой вопрос по-любому подходит. Искал-искал на этом сайте и в инете, но не попалось ничего по проблеме, с которой столкнулся.
Кто может толково разъяснить, что творится со страницей после присвоение дополнительной строки к body.innerhtml? У меня впечатление, что в ДОМе всё слетает нафик после такой казалось бы безобидной операции. Ну, т.е. отдельный скрипт добавляет в документ новый div со всем его содержимым, используя для этого body.innerhtml: body.innerhtml = '<div>что-то там</div>' + body.innerhtml; И после этого на странице начинаются чудеса. Я понимаю, что эту проблему можно обойти путём аккуратного присоединения нового узла к документу. Однако хочется основательно понять, что чем обусловлены глюки, возникающие при использовании body.innerhtml. Заметил следующие глюки: 1. Слетают все указатели, полученные прежде по getElementById. То есть происходит в реале ещё более странно: прежние объекты, на которые получен указатель, продолжают существовать и жить своей жизнью, но на экране они не видны, а вместо них появляются их двойники с теми же ИД. 2. Нарушается позиционирование элементов на странице. Т.е., например, top отсчитывается словно не от нуля, а со положительным смещением. 3. Да и вообще страница словно заново перегружается (счетчики дважды обновляются). Я это ещё мог бы понять, если бы вообще все объекты, созданные после первой загрузки, напрочь удалялись при повторной загрузке. Однако это не так - см. п.1. 4. Ну, и соответственно, обработчик onLoad глючит конкретно: выполнение его прерывается после выполнения строки "body.innerhtml = ...", но после повторной загрузки страницы он всё же второй раз не вызывается. При таких глюках было бы правильнее, КМК, вообще изъять innerhtml у body. С другими тэгами таких глюков не заметил. Чтобы проиллюстрировать эти проблемы, могу предложить сравнить нормальную работу скрипта, фиксирующего положение <div> и обеспечивающего прокрутку страницы, и его нарушенную работу при его взаимодействии со скриптом, добавляющим в документ новый div вышеуказанным способом. "Нормальный" скрипт лежит тут... Он содержит два класса: автоматический прокрутчик страницы и фиксатор div-ов. Пример нормальной работы кода обоих классов можно увидеть на главной странице моего сайта... Нажатие любой клавиши включает/выключает автопрокрутку. А после прокрутки на пол-окна плавно появляется справа ссылка "Наверх". Или вот тут пример автопрокрутки при иных параметрах. А здесь пример одновременной фиксации двух div-вов (навешиваются списком к классу "фиксатор"). Примером нарушенной работы того же самого кода можно полюбоваться тут... То есть, после того, как к странице присоединяется меню при помощи "body.innerhtml = ...", в результате возникают перечисленные выше глюки. Код для "меню" лежит здесь... |
Цитата:
Цитата:
Допустим у нас есть такой HTML код: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Пример</title> </head> <body> <h2 id="h2">Заголовок</h2> </body> </html> И мы через JS делаем: var h2 = document.getElementById("h2"), h2byName = document.getElementsByTagName("h2"), myBody = document.getElementsByTagName("body")[0]; myBody.innerHTML = myBody.innerHTML; h2.innerHTML = "Пыщ Пыщ!"; // Упс! Кажется бага h2byName[0].innerHTML = "Пыщ Пыщ!"; // Ура, всё ок! Цитата:
Цитата:
Цитата:
Цитата:
Вообще свойство innerHTML может часто вызывать недопонимание, например если вставить тег script через innerHTML, то он не будет работать) Я думаю, что при вставки кода таким способом браузер рендерит строку, но не выделяет память на всякие "физические" операции, типо там выполнение скрипта или подгрузка стилей и т.д. |
Ну, по нескольким пунктам никак не могу тут согласиться с "логичностью".
Цитата:
"Мёртвая" ссылка должна быть именно мёртвой после сброса всего содержимого body. Однако в реальности приходится сталкиваться с тем, что после перезагрузки страницы сохранилась не только сама переменная ptrID, но и тот объект, на который она ссылалась до перезагрузки. Так быть не должно, ИМХО. Это крайне нелогично. С onLoad тоже логики не вижу. Если я сбросил всё содержимое body, как Вы выразились, и браузер фактически загрузил снова все объекты по второму разу (что отражается на счетчике, к примеру), то и событие onLoad он должен был бы вызвать повторно (а обработчик его ведь так и висит на body, поскольку изменен был innerHTML, а не outerHTML). Ну, т.е. итог: вижу, что этого всего абсурда обойти не удастся кроме как цеплять div через createElement. И, похоже, что body.innerHTML лучше вообще не трогать, ибо при работе с ним мы всегда сначала создаём его копию, а затем совершаем присвоение со всеми неизбежными неприятностями. |
Цитата:
Цитата:
Цитата:
Цитата:
|
Цитата:
Например, var el = document.createElement('div'); // Создали новый div, в дереве его нет, он не отображается, но он существует el.style.color = 'red'; // можем менять его свойства // можем добавлять ему детей, если надо document.body.appendChild(div); // вот теперь мы его добавили в существующее дерево, теперь он отобразится. document.body.removeChild(div); // а теперь удалили из дерева, он теперь не отображается, но по прежнему существует. document.body.appendChild(div); // мы его может повторно в дерево засунуть. |
Цитата:
Цитата:
|
Ох-ох-ох))))) Да, уж, к этому нужно привыкнуть...
Спасибо всем вам за весьма толковые разъяснения! |
Часовой пояс GMT +3, время: 08:36. |