getBoundingClientRect () возвращает ноль в XUL

у меня проблема с моим расширением firefox

у меня есть всплывающая панель XUL с hbox для облака тегов и код JS для добавления divs в этот hbox:

<hbox id="tag_base" ondblclick="alert('done')"/>

JS:

var root = document.getElementById('tag_base');
var tag = document.createElement('div');
tag.textContent = 'test';
root.appendChild(tag);
var rect = tag.getBoundingClientRect()
alert(rect.top)

мне нужно получить размеры каждого добавленного div, однако getBoundingClientRect просто отказывается работать. Если я удаляю предупреждения, они всегда равны нулю. С предупреждениями история отличается: При первом вызове предупреждения он возвращает ноль, хотя div появляется на экране. Все последующие оповещения возвращают правильные координаты.

Если я установил точку останова в Chromebug, все сообщается правильно. Если я никак не вмешиваюсь в выполнение и запускаю цикл, возвращаются только нули.

Это меня совсем запутало. Вызов " boxObject "дает те же результаты, в то время как" getClientRects[0] " не определен при первом вызове.

любые намеки на то, что может быть причиной этого, будут высоко оценены.

3 ответов


хотя я не могу найти любой документация по этой, казалось бы, фундаментальной проблеме, проблема, которую вы заметили, скорее всего, потому, что процесс компоновки (он же "reflow") еще не запущен к моменту запроса координат.

процесс layout/reflow принимает DOM страницы с любыми стилями страницы и определяет позиции и размеры элементов и других частей страницы (вы можете попробовать прочитать примечания по HTML reflow, хотя он не предназначен для веб-разработчиков и, вероятно, немного устарел).

этот процесс reflow не запускается синхронно после каких-либо изменений в DOM, в противном случае код, как

elt.style.top = "5px";
elt.style.left = "15px";

обновит макет дважды, что неэффективно.

С другой стороны, запрашивая положение/размер элементов (по крайней мере, через .offsetTop) должен заставить макет возвращать правильную информацию. Это не произойдет в вашем случае по какой-то причине и я не уверен почему?.

пожалуйста, создайте простой testcase, демонстрирующий проблему и файл ошибка в bugzilla.mozilla.org (CC me - asqueella@gmail.com).

Я предполагаю, что это связано с макетом XUL, который менее надежен, чем HTML; вы можете попробовать создать облако в HTML-документе в iframe или, по крайней мере, в , используя createElementNS для создания реальных HTML-элементов вместо xul: div вы создаете с вашим текущим кодом.


Примечание. : Внимание! если вы используете getBoundingClientRect с элементом, который имеет display: none, он вернет 0 в любом месте dom.


убедитесь, что DOM готов. В моем случае, даже при использовании getBoundingClientRect функция на событиях щелчка. Привязка событий, необходимых для того, чтобы произойти, когда DOM будет готов.