获取组件的实际宽度和高度 [英] Get actual width and height of a component

查看:133
本文介绍了获取组件的实际宽度和高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在JavaScript中面临一个相当可怕的问题,我们似乎没有一个能够解决:

We're facing a fairly scary issue in JavaScript that none of us seems to be quite capable of resolving:

我们如何获得DOM元素,包括儿童,整个框模型等,而没有实际显示在页面上的组件?

How do we get the width and height of a DOM element, including children, entire box model etc. without the component actually being displayed on the page?

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

Remember: I'm looking for suggestions. Even answers which don't answer the question fully (or don't quite fit with the specified parameters) might, and probably will, be helpful.

主要目标:通过Javascript将HTML元素添加到页面中 - 从数据库中获取具有大小和样式的HTML元素。问题是,他们的行为不当,通常是不良的分配,一个元素大于另一个因为填充/边缘任何,所以我需要检查他们的实际大小来解决这些问题。

Main goal: I'm adding HTML elements into the page via Javascript - HTML elements with sizes and styles from a database. Problem is that they misbehave, usually bad aligment, one element is larger than another due to padding/margin whatever, and so I need to check their actual size to fix these issues.

由此产生的应用程序将是一个,因为BigMacAttack在评论中描述了它,一个第三方HTML控件的紧密结合的马赛克将几乎是现货。它需要看起来很像完整的桌面应用程序,而HTML似乎讨厌这个想法与激情。

The resulting application is going to be a, as BigMacAttack has described it in the comments, a 'tightly knit mosaic of 3rd-party HTML controls' would pretty much be spot-on. It needs to look a lot like full-fledged desktop application, and HTML seems to hate the idea with passion. Not that I blame it.

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

Anyway, here's some example code:

JavaScript:

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);
};

CSS:

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

.exampleElement .exampleP {
    padding: 20px;
    margin: 6px;
}

小提琴

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

Now, we need our page to dynamically react to size of the window and to contents of individual components, that's why it's important to be able to get size of an object before even displaying it. It's also important that creation of an object is clearly separated into three phases:


  • 通过新建

  • creation via new

构建DOM树(constructElement)

construction of DOM tree (constructElement)

添加到文档中)

重要的是我们知道施工阶段各个元素的大小。

It's important that we know sizes of individual elements during the construction phase.

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

So far we've tried measuring it via jQuery, DOM width and height attributes, but none of that works with DOM object not being directly displayed on page. Another approach I have tried were several functions adding the object into document.body, getting width and height, and then immediately removing it - however, since our CSS files are very specific, this is unreliable unless you insert the entire rootElement, which will be a terrible performance and memory hog as our components get fairly complex.

我假设一个方法完全删除.CSS文件和直接通过JS定义样式将解决至少部分我们的困境,但必须有一个更好的方法。

I suppose an approach of dropping .CSS files completely and defining styles directly trough JS would solve at least part of our predicament, but there has to be a better way.

开始赏金来获得更多的想法和建议。只是拍摄人,即使答案不完全在问题的边界内(你将如何/你做的等等) - 我想实现的目标是我的JS生成的HTML控件适当地组合在一起。 p>

Starting bounty to get more ideas and suggestions. Just shoot people, even if answer is not entirely within the boundaries of the question (how would/did you do it etc.) - the goal I'm trying to achieve is for my JS generated HTML controls to properly fit together.

推荐答案

使用javascript获取框架模型DOM节点的渲染宽度和高度,而不实际将其添加到要显示的DOM

Getting the rendered width and height of a box-model DOM node using javascript without actually adding it to the DOM to be displayed is not possible.

为了证明这一点,让我们来看一下如何在浏览器内部计算渲染的DOM节点的高度和宽度。

To prove this, let's walk through how the rendered height and width of a DOM node is calculated internally to the browser. I will reference how WebKit handles this since it is the most commonly used layout engine.

由于文档被解析并且DOM节点被添加到DOM树中,因此我将引用WebKit处理这个问题,因为它是最常用的布局引擎。 code> Renderers 是为需要显示的DOM节点创建的。这是渲染树的构建方式。

As the document is parsed and DOM nodes are added to the "DOM Tree", Renderers are created for the DOM nodes that need to be displayed. This is how the "Render Tree" gets built.

这是一篇摘录自
$ / $ / $ / $ / $ / 114 / webcore-rendering-i-the-basics /rel =nofollow>WebCore Rendering I - The Basics b $ b

Here is an excerpt from an article entitled "WebCore Rendering I – The Basics" by Dave Hyatt on the official WebKit Blog:


通过DOM上的一个名为attachment的过程创建渲染器
当一个文档被解析并且添加了DOM节点时,一个叫做
<$

"Renderers are created through a process on the DOM called attachment. As a document is parsed and DOM nodes are added, a method called attach gets called on the DOM nodes to create the renderers.

void attach()

void attach()

attach 方法计算DOM节点的样式信息,如果
显示CSS元素的CSS属性设置为none或者如果节点是
a子元素的display:none set,那么不会创建渲染器

The attach method computes style information for the DOM node. If the display CSS property for the element is set to none or if the node is a descendant of an element with display: none set, then no renderer will be created."

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

So, in order to be efficient, the browser does not even bother computing style information for elements with display set to none. As a result, the information is not available to be accessed via javascript. However, if the display property is not set to none, the following occurs:


查询CSS以获取
元素的样式信息,结果信息存储在一个名为
的对象中RenderStyle ... RenderStyle可以使用style()方法从RenderObject
访问... RenderObject的主要工作子类
之一是RenderBox,这个子类表示
服从CSS框模型的对象,包括具有边框的任何对象,
padding,margin,width和高度。

"During attachment the DOM queries CSS to obtain style information for an element. The resultant information is stored in an object called a RenderStyle... The RenderStyle can be accessed from a RenderObject using the style() method... One of the principal workhorse subclasses of RenderObject is RenderBox. This subclass represents objects that obey the CSS box model. These include any objects that have borders, padding, margins, width and height."

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

So if your use case allows for you to retrieve the box-model rendering height and width via C/C++ directly from the browser and pass it to your javascript code via some other means, then you could query the height/width methods of the RenderBox subclass of each DOM element. This is basically how the WebKit Developer Tools gets this information.

这篇关于获取组件的实际宽度和高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆