Проблемы с порядком выполнения кода в Dojo framework

Столкнулся с странной проблемой при работе с Dojo. Вот мой код:

var position = dojo.coords(element);
element.style.left = position.x + "px";
element.style.top = position.y + "px";
element.style.position = "absolute";

У меня есть элемент element с относительным позиционированием. Координаты x равны 70, а y равны 30. Когда я убираю последнюю строку с position = "absolute", то dojo.coords(element) возвращает правильные значения. Но если добавляю эту строку обратно, то x становится равным 18. Это значение соответствует абсолютному позиционированию элемента.

Мне кажется очень странным, что вызов dojo.coords() как-то зависит от кода который идет после него. Разве так должно быть?

Также замечаю похожую проблему с dojo.require(). Если вызываю его прямо перед функцией которую он загружает, получаю ошибку что функция не определена.

Тестирую в Firefox 3 и Safari 3. Кто-нибудь сталкивался с таким? Как это исправить?

Браузер пересчитывает layout сразу после изменения CSS свойств. Это reflow, он происходит синхронно. Когда ставишь position: absolute, элемент выпадает из потока документа и координаты меняются моментально.

Попробуй dojo.marginBox() вместо coords() - он учитывает только размеры без позиционирования. Или клонируй элемент для получения исходных координат:

var clone = element.cloneNode(true);
var position = dojo.coords(clone);
// потом работай с оригиналом

Так получишь стабильные значения независимо от дальнейших изменений стилей.

Да, это нормально для dojo.coords(). Функция считает координаты элемента прямо сейчас, на основе его текущего состояния в DOM. Когда меняешь position на absolute, элемент сразу двигается и координаты пересчитываются.

Решение простое - сохрани координаты перед изменением позиционирования:

var position = dojo.coords(element);
element.style.position = "absolute";
element.style.left = position.x + "px";
element.style.top = position.y + "px";

С dojo.require() та же история. Модули грузятся асинхронно, поэтому используй колбэки или dojo.ready(). И помни - DOM обновляется мгновенно при любых изменениях стилей.

Попробуй dojo.position() вместо coords() — она дает позицию относительно родителя, а не всего документа. Может поможет с reflow. Или через getComputedStyle() получи left/top до изменения позиционирования. Какой результат нужен в итоге?