获取组件的实际宽度和高度

Fen*_*ixp 17 html javascript css jquery dom

我们在JavaScript中遇到了一个相当可怕的问题,我们似乎都没有能力解决:

我们如何获得DOM元素的宽度和高度,包括子元素,整个盒子模型等,而不会在页面上显示组件?

记住:我正在寻找建议.即使没有完全回答问题(或者不完全符合指定参数)的答案也可能,而且可能会有所帮助.

主要目标:我通过Javascript将HTML元素添加到页面中 - 来自数据库的大小和样式的HTML元素.问题是他们行为不端,通常是不好的对齐,由于填充/边距,一个元素比另一个元素大,所以我需要检查它们的实际大小来解决这些问题.

由此产生的应用程序将成为一个,正如BigMacAttack在评论中所描述的那样,"紧密结合的第三方HTML控件拼接"几乎可以在现场进行.它需要看起来像完全成熟的桌面应用程序,HTML似乎充满激情地讨厌这个想法.不是我责备它.

无论如何,这是一些示例代码:

JavaScript的:

function exampleElement(caption, content) {
    this.caption = caption;
    this.content = content;
    this.rootElement = document.createElement("div");
}

exampleElement.prototype.constructElement = function() {
    var otherElement = document.createElement("p");
    this.rootElement.className = "exampleElement";
    this.rootElement.textContent = this.caption; 
    otherElement.className = "exampleP";
    otherElement.textContent = this.content;
    this.rootElement.appendChild(otherElement);
    /*I need to know size of the otherElement here*/
    /*here goes code adding stuff into rootElement*/
};

window.onload = function() {
    var ex = new exampleElement("Hello", "Here's text");
    ex.constructElement();
    document.body.appendChild(ex.rootElement);
};
Run Code Online (Sandbox Code Playgroud)

CSS:

.exampleElement {
    padding: 5px;
    margin: 6px;
}

.exampleElement .exampleP {
    padding: 20px;
    margin: 6px;
}
Run Code Online (Sandbox Code Playgroud)

小提琴

现在,我们需要页面动态地响应窗口大小和单个组件的内容,这就是为什么在显示对象之前能够获得对象大小的重要性.同样重要的是,对象的创建明确分为三个阶段:

  • 通过新的创造

  • DOM树的构造(constructElement)

  • 添加到文档中(直接进入正文或进入另一个DOM树)

重要的是我们在施工阶段了解各个元素的尺寸.

到目前为止,我们已经尝试通过jQuery,DOM宽度和高度属性来测量它,但是这些都不能直接在页面上显示DOM对象.我尝试过的另一种方法是将几个函数添加到document.body中,获取宽度和高度,然后立即删除它 - 但是,由于我们的CSS文件非常具体,除非插入整个rootElement,否则这是不可靠的由于我们的组件变得相当复杂,所以性能和内存都很糟糕.

我认为完全删除.CSS文件并直接通过JS定义样式的方法至少可以解决部分困境,但必须有更好的方法.

开始赏金以获得更多想法和建议.只是拍摄人物,即使答案不完全在问题的范围内(你会怎么做/等等) - 我试图实现的目标是让我生成的JS控件正确地组合在一起.

Ker*_*Liu 10

如果您需要最初隐藏手风琴,滑块等需要边界框信息才能正常工作的组件,您经常遇到此问题.

一个简单的技巧是添加隐藏相关内容可见性的css,并确保它不会闪烁或导致布局干扰.

它可以是一样简单:

{   visibility:hidden;
    position:absolute;
    left: -9999px;
}
Run Code Online (Sandbox Code Playgroud)

然后,当您准备好显示组件时,将位置设置回静态或相对,并将可见性恢复为可见.

小提琴在这里,但它没有多少:http://jsfiddle.net/gwwar/ZqQtz/1/


Big*_*ack 5

使用 javascript 获取盒模型 DOM 节点的渲染宽度和高度而不实际将其添加到要显示的 DOM 中是不可能的。

为了证明这一点,让我们来看看如何在浏览器内部计算 DOM 节点的渲染高度和宽度。我将参考 WebKit 如何处理这个,因为它是最常用的布局引擎。

随着文档被解析并将 DOM 节点添加到“DOM 树”中,Renderers为需要显示的 DOM 节点创建。这就是“渲染树”的构建方式。

以下是Dave Hyatt 在官方 WebKit 博客上题为“WebCore Rendering I – The Basics”的文章的摘录:

“渲染器是通过 DOM 上称为附件的过程创建的。当解析文档并添加 DOM 节点时,attach会在 DOM 节点上调用一个名为的方法 来创建渲染器。

void attach()

attach方法计算 DOM 节点的样式信息。如果元素的 display CSS 属性设置为 none 或者如果节点是设置了 display: none 的元素的后代,则不会创建渲染器。”

因此,为了提高效率,浏览器甚至不会为 display 设置为 none 的元素计算样式信息。因此,无法通过 javascript 访问该信息。但是,如果 display 属性设置为 none,则会发生以下情况:

“在附加期间,DOM 查询 CSS 以获取元素的样式信息。结果信息存储在一个称为 RenderStyle 的对象中……可以使用 style() 方法从 RenderObject 访问 RenderStyle……其中一个原理RenderObject 的主力子类是 RenderBox。这个子类表示遵守 CSS 框模型的对象。这些对象包括任何具有边框、填充、边距、宽度和高度的对象。”

因此,如果您的用例允许您直接从浏览器中通过 C/C++ 检索盒模型渲染高度和宽度,并通过其他方式将其传递给您的 javascript 代码,那么您可以查询 RenderBox 的高度/宽度方法每个 DOM 元素的子类。这基本上是 WebKit 开发人员工具获取此信息的方式。