获取组件的实际宽度和高度
Get actual width and height of a component
我们在 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);
};
.CSS:
.exampleElement {
padding: 5px;
margin: 6px;
}
.exampleElement .exampleP {
padding: 20px;
margin: 6px;
}
小提琴
现在,我们需要我们的页面对窗口的大小和各个组件的内容做出动态反应,这就是为什么能够在显示对象之前获取对象的大小很重要的原因。同样重要的是,对象的创建应明确分为三个阶段:
通过新创建
DOM 树的构造 (constructElement)
添加到文档中(直接添加到正文或另一个 DOM 树中)
施工阶段,我们必须了解各个元素的尺寸,这一点很重要。
到目前为止,我们已经尝试通过jQuery,DOM宽度和高度属性来测量它,但是对于DOM对象没有直接显示在页面上,这些都不起作用。我尝试过的另一种方法是将对象添加到 document.body 中的几个函数,获取宽度和高度,然后立即将其删除 - 但是,由于我们的 CSS 文件非常具体,除非您插入整个 rootElement,否则这是不可靠的,这将是一个糟糕的性能和内存消耗,因为我们的组件变得相当复杂。
我想一种放弃的方法.完全CSS文件并直接通过JS定义样式至少可以解决我们的部分困境,但必须有更好的方法。
开始赏金以获得更多的想法和建议。只需射击人,即使答案不完全在问题的范围内(你会/你怎么做等) - 我试图实现的目标是让我的 JS 生成的 HTML 控件正确组合在一起。
如果最初需要隐藏手风琴、滑块等组件以及需要边界框信息才能正常工作的其他组件,则经常会遇到此问题。
一个简单的技巧是添加css,隐藏相关内容的可见性,并确保它不会闪烁或干扰您的布局。
它可以像这样简单:
{ visibility:hidden;
position:absolute;
left: -9999px;
}
然后将位置设置回静态或相对,并在准备好显示组件时将可见性设置回可见。
小提琴在这里,但没有太多内容:http://jsfiddle.net/gwwar/ZqQtz/1/
使用 javascript 获取盒模型 DOM 节点的渲染宽度和高度,而不实际将其添加到要显示的 DOM 中是不可能的。
为了证明这一点,让我们来看看如何在浏览器内部计算 DOM 节点的渲染高度和宽度。我将参考 WebKit 如何处理这个问题,因为它是最常用的布局引擎。
随着文档的解析和 DOM 节点添加到"DOM 树"中,会为需要显示的 DOM 节点创建Renderers
。这就是"渲染树"的构建方式。
以下是Dave Hyatt在官方WebKit博客上发表的一篇题为"WebCore Rendering I – The Basics"的文章的摘录:
"渲染器是通过DOM上称为附件的过程创建的。 在解析文档并添加 DOM 节点时,一种名为
attach
在 DOM 节点上被调用以创建渲染器。
void attach()
attach
方法计算 DOM 节点的样式信息。如果 元素的显示 CSS 属性设置为无,或者如果节点是 具有 display:未设置,然后无渲染器的元素的后代 将被创建。
因此,为了提高效率,浏览器甚至不会为显示设置为none的元素计算样式信息。因此,无法通过javascript访问该信息。但是,如果显示属性未设置为 none,则会发生以下情况:
"在附件期间,DOM 查询 CSS 以获取 一个元素。生成的信息存储在名为 渲染样式...可以从 RenderObject 访问 RenderStyle 使用 style() 方法...主要主力子类之一 的 RenderObject 是 RenderBox。此子类表示以下对象: 遵守 CSS 框模型。这些包括任何有边框的对象, 填充、边距、宽度和高度。
因此,如果您的用例允许您直接从浏览器中通过 C/C++ 检索盒模型渲染高度和宽度,并通过其他方式将其传递给您的 JavaScript 代码,那么您可以查询每个 DOM 元素的 RenderBox 子类的高度/宽度方法。这基本上就是 WebKit 开发人员工具获取此信息的方式。
你可以试试这个jQuery插件:https://github.com/dreamerslab/jquery.actual
既然你问了相关的答案...
如果您的 DOM 元素不按其内容动态调整大小,我建议使用以下工作流程。
虽然它可以让你的 DOM 结构更加臃肿,但通常最好使用"容器"对象。 这些对象将没有边框、填充或边距,以保持其 DOM 尺寸可预测。然后,您可以强制孩子在其容器的范围内紧紧扩展。
容器对象将用于查询特定的大小和位置,因为没有额外的属性来解释大小失真。
http://jsfiddle.net/aywS6/
.CSS
#container {
position: absolute;
margin:0px;
padding:0px;
width: 300px;
height: 100px;
background: #aaa;
border: 0 none;
}
#subject {
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
padding: 10px 20px;
background: #aaf;
}
.HTML
<div id="container">
<div id="subject">
contents...
</div>
</div>
这里的问题是,在页面上添加此元素之前,您无法获取元素大小。
在您的方法"constructElement"上,您将元素添加到根元素,但只是在加载时添加到页面。您的属性"rootElement"没有设置大小属性。
如果要操作这些属性,请重新考虑对象/方法的结构。
看看我对你的小提琴的更新
$(function ()
{
var ex = new exampleElement("Hello", "Here's text");
ex.constructElement();
document.body.appendChild(ex.rootElement);
$("<span/>")
.text(" => Width is " + $("div").width() + ", and Height is " + $("div").height())
.appendTo($("div p"));
});
不知道这是否有帮助,但既然你问了任何答案:)这是我所拥有的。
我有一个类似的问题,我想有很好的jQuery效果,根据HTML容器的内部内容将它的大小调整为"自动"高度和宽度。这个想法仍然类似于一些人已经在这里提到的:你在"屏幕外"的某个地方有一个容器,你把你的东西放在那里,测量尺寸并删除它。所以这是我在这里找到的功能
jQuery.fn.animateAuto = function(prop, speed, callback) {
var elem, height, width;
return this.each(function(i, el) {
el = jQuery(el), elem = el.clone().css({
"height" : "auto",
"width" : "auto"
}).appendTo("body");
height = elem.css("height"), width = elem.css("width"), elem.remove();
if (prop === "height")
el.animate({
"height" : height
}, speed, callback);
else if (prop === "width")
el.animate({
"width" : width
}, speed, callback);
else if (prop === "both")
el.animate({
"width" : width,
"height" : height
}, speed, callback);
});
};
这段代码比你需要的多一点,但你可能感兴趣的部分是这样的:
elem = el.clone().css({
"height" : "auto",
"width" : "auto"
}).appendTo("body");
height = elem.css("height")
width = elem.css("width")
希望这有帮助
如果主要问题是您无法在将其放置到屏幕上之前获取大小,我建议您创建一个允许将div 隐藏在页面背景下的类。这应该跨浏览器工作。
.exampleHidden{
position: absolute;
z-index: -1;
}
如果将页面 z-index 的主背景设置为 0,则将隐藏类附加到新元素,它会将其置于背景下。假设它不大于你的背景,它现在应该被隐藏,以允许你在通过删除.exampleHidden 类将其实际带回前台之前测量和设置高度和宽度。
- electronic BrowserWindow的最小高度和宽度在hide()show()方法之后不起作用
- React重新渲染但未显示正确的组件
- 不能从angular2中的子组件指定父组件中的数组
- 拨打'父亲'函数形式a'儿童'ReactJS中的组件
- ExtJS——在展开/折叠时调整面板高度
- 分析高度属性时出现意外值{{specs.height}}.index.html
- React组件等待所需道具进行渲染
- 如何创建带有插槽的vue js组件预加载程序
- KnockoutJS-组件-多个实例
- 单击页面上的链接后高度发生变化
- 如何更改reactjs中外部/独立组件的状态或属性
- 如何在react js中将值从一个组件发送到另一个组件
- 不加载宽度和高度的角度pintura
- React Native通过Navigator将用户输入数据传递到选项卡栏IOS中的组件
- React组件-设置页面标题
- 获取嵌套在聚合物纸张对话框中的自定义Web组件内内容的客户端高度
- 获取组件的实际宽度和高度
- 在反应组件中查找正文内容的高度
- 更改EXTjs的ext.tab.Tab组件的高度或添加填充
- 如何将html中组件的高度设置为父组件的高度