Реализация DOM
Всем доброго дня!!! Пытаюсь глубже понять реализацию DOM в браузерах и недавно наткнулся на такой случай. Есть обычная страница:
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>анимация переходы</title> <style> div { width: 300px; height: 300px; background-color: red; opacity: 1; transition-property: all; transition-duration: 1s; } #d { width: 300px; height: 300px; background-color: blue; opacity: 0; transition-property: all; transition-duration: 1s; } </style> </head> <body> <button id="btn">click</button> <div></div> <div id="d"></div> <script> var div = document.getElementsByTagName("div")[0]; var d = document.getElementById("d"); document.body.removeChild(d); var button = document.getElementById("btn"); </script> </body> </html> В стиле описан переход transition, элемент <div id="d"> сразу же удаляю из DOM(можно просто создать его и хранить в переменной). Если кликнуть по кнопке, то js изменить opacity элемента и мы видим плавный переход. Вот 2 реализации в js 1) var div = document.getElementsByTagName("div")[0]; var d = document.getElementById("d"); document.body.removeChild(d); var button = document.getElementById("btn"); button.onclick = function() { div.style.opacity = 0; setTimeout(function(){ document.body.appendChild(d); d.style.opacity = 1; },1000); } В данной реализации, появление второго div-а , происходит резко(без перехода). Но если добавить таймаут, то переход будет плавный. 2) var div = document.getElementsByTagName("div")[0]; var d = document.getElementById("d"); document.body.removeChild(d); var button = document.getElementById("btn"); button.onclick = function() { div.style.opacity = 0; setTimeout(function(){ document.body.appendChild(d); setTimeout(function() { d.style.opacity = 1; },100); },1000); } С чем это связано? Данная проблема возникает, если вставить в DOM элемент, а затем изменить style. Если же элемент есть в DOM, то все работает плавно. Проверено в IE11, chrome ff последних версий. Мастера js дайте подсказку и рекомендации. Спасибо! |
Возможно какое то время тратится на отрисовку созданого динамически элемента. Т.е по факту в дереве DOM он уже присутвует но не отрисован самим броузером.Когда броузер его отобразит произойдет смещение по времени и мы увидим почти мгновенное отображение, но на самом деле плавное.Javascript да однопоточен, но когда он выполнит инструкцию document.body.appendChild(d); это не значит что отобразит его, а перейдет к следующей d.style.opacity = 1; И пройзойдет смещение. Скорее всего это можно отнести к багу.
|
Да, действительно похоже на баг. Я тебе больше скажу, посмотри на мой вариант:
<button id="btn">smooth</button><br/> <div></div> <div id="d"></div> <style> div { display:inline-block; width: 100px; height: 100px; background-color: red; opacity: 1; transition-property: all; transition-duration: 1000ms; } #d { background-color: blue; opacity: 0; } </style> <script> var div = document.getElementsByTagName("div")[0]; var d = document.getElementById("d"); d.parentNode.removeChild(d); document.getElementById("btn").onclick = function () { div.style.opacity = 0; setTimeout(function(){ document.body.appendChild(d); *!* console.log(d.offsetTop); */!* d.style.opacity = 1; }, 1000); }; </script> Видимо, это как-то связано с оптимизацией обращений к DOM. Есть там какая-то хитрота, не помню точно, отпишу, если найду. |
Спасибо! Буду дальше разбираться, буду ждать новых сообщений.
|
Часовой пояс GMT +3, время: 14:40. |