getBoundingClientRect()在XUL中返回零

And*_*ch. 9 dom xul coordinates

我的firefox扩展有问题

我有一个XUL弹出面板,带有一个用于标签云的hbox,以及一个用于向这个hbox添加div的JS代码:

<hbox id="tag_base" ondblclick="alert('done')"/>
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

我需要获取每个添加的div的维度,但是,getBoundingClientRect只是拒绝工作.如果我删除警报,它总是为零.通过警报,故事情况有所不同:第一次调用警报时,它会返回零,尽管div出现在屏幕上.任何后续警报都会返回正确的坐标.

如果我在Chromebug中设置断点,则会正确报告所有内容.如果我没有以任何方式中断执行,并运行循环,则只返回零.

这让我很困惑.调用"boxObject"会产生相同的结果,而"getClientRects [0]"在第一次调用时未定义.

任何可能导致此问题的提示都将不胜感激.

小智 25

注意:注意,如果你将getBoundingClientRect与一个display:none的元素一起使用,那么它将在dom中的任何地方返回0.

  • 老帖但这正是我的问题所在. (2认同)
  • 救了我的一天!谢谢! (2认同)
  • 非常感谢!我将`getBoundingClientRect` 与bootstrap 的模态一起使用,并将它们全部设为0。然后我再次尝试使用 `shown.bs.modal`,它应该可以工作。再次感谢你! (2认同)

Flo*_*ris 7

确保 DOM 已准备就绪。就我而言,即使getBoundingClientRect在单击事件上使用该函数也是如此。当 DOM 准备好时需要发生事件的绑定。


Nic*_*lay 5

虽然我找不到关于这个看似基本问题的任何文档,但您注意到的问题很可能是因为在您要求坐标时布局(又名“回流”)过程尚未运行。

布局/回流过程采用页面具有的任何样式的页面的 DOM,并确定元素和页面其他部分的位置和尺寸(您可以尝试阅读HTML 回流的注释,尽管它不是针对 Web 开发人员的,并且可能有点过时了)。

在对 DOM 进行任何更改后,此回流过程不会同步运行,否则代码如下

elt.style.top = "5px";
elt.style.left = "15px";
Run Code Online (Sandbox Code Playgroud)

会更新布局两次,这是低效的。

另一方面,要求元素位置/尺寸(至少通过.offsetTop)应该强制布局返回正确的信息。由于某种原因,这不会发生在您的情况下,我不确定为什么。

请创建一个简单的测试用例来演示问题并在 bugzilla.mozilla.org 中提交错误(抄送我 - asqueella@gmail.com)。

我的猜测是这与 XUL 布局有关,它不如 HTML 健壮;您可以尝试在 iframe 中的 HTML 文档中创建云,或者至少在 <description> 中使用 createElementNS 创建真正的 HTML 元素,而不是使用当前代码创建的 xul:div

  • 这可能是因为弹出窗口在第一次显示之前不会发生布局,除非在菜单列表的情况下,因为弹出窗口必须布局以便列表可以调整大小。 (2认同)