有什么方法可以在将元素附加到 DOM 之前获取其高度吗?我知道 clientHeight 无法像我尝试的那样工作,它总是返回 0。是否有其他方法可以返回高度,或者元素是否必须是 DOM 的一部分才能计算高度?
这是我想要的示例:
function test(a) {
var a=document.createElement(a)
a.style.top=(window.innerHeight/2-a.clientHeight/2)+'px' //fixed position in CSS
document.body.appendChild(a)
}
*注意:这只是我正在开发的功能的简化版本,以便投影我想要实现的目标,而不会出现所有不必要的混乱。
元素在被添加到 DOM 之前,在任何真正意义上都没有有高度,因为在此之前无法评估它们的样式。
您可以使用
visibility: hidden
轻松解决此问题,以便可以将元素添加到 DOM(并确定其高度),而不会导致可见的闪烁。
function test(a) {
var a = document.createElement(a);
a.style.visibility = 'hidden';
document.body.appendChild(a);
a.appendChild(document.createTextNode('Hello'));
a.style.fontStyle = 'italic';
a.style.top=(window.innerHeight/2 - a.clientHeight/2) + 'px';
a.style.visibility = '';
return a;
}
test('p').style.background = '#0f0';
p { position: absolute; top: 0; left: 0; }
(这是假设您正在使用
top
,因为该元素是绝对定位或固定的。如果不是,您需要暂时如此。)隐藏元素仍然占用空间DOM(因此必须计算它们的大小),但用户实际上无法看到。
如果 DOM 节点的高度是/可以是动态的,那么你可能无法在 DOM 中存在之前测量它,除非你以某种方式考虑到所有可能的情况(字体大小、填充/边距/边框、实际大小)等)
一个可行的选择是将节点注入到 DOM 中,在视觉上隐藏并测量事物,然后才显示它。这是一个如何测量元素的工作演示,方法是“简单地”将其添加到 DOM 并检查其高度,然后将其删除。此方法可能成本较高,因为节点是克隆的,因此添加的样式不会影响之后的节点,并且所有
DOM 事件 都将从节点中删除。 如果检查的节点有很多子节点,这可能效率不高,但仍然非常方便。
function getNodeHeight(node) {
var height, clone = node.cloneNode(true)
// hide the meassured (cloned) element
clone.style.cssText = "position:fixed; top:-9999px; opacity:0;"
// add the clone to the DOM
document.body.appendChild(clone)
// meassure it
height = clone.clientHeight
// cleaup
clone.parentNode.removeChild(clone)
return height
}
var newDiv = document.createElement("div");
newDiv.innerHTML = `Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
<h1>deserunt mollit anim id est laborum.<h1>`
// print the height of "newDiv"
console.log( getNodeHeight(newDiv) )
在将元素添加到 DOM 之前,我认为这是不可能的,除非您事先知道涉及的所有变量(不太可能)。
屏幕具有刷新率(每秒显示的最大图像数),因此不可能在 DOM 所做的每次更改时渲染页面。
当渲染 DOM 时,会调用 requestAnimationFrame。当它被调用时,意味着屏幕即将更新。在这里您可以获取元素的属性并更改它们。
您甚至可以通过调用cancelAnimationFrame来取消此帧。
https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame