在添加到 DOM 之前获取元素的高度

发布于 2024-11-06 19:10:53 字数 397 浏览 0 评论 0原文

在将元素附加到 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)
    }

*注意:这只是我正在开发的功能的简化版本,以便投影我想要实现的目标,而不会出现所有不必要的混乱。

Is there any way to get an element's height prior to appending it to the DOM? I know that clientHeight doesn't work as I've tried and it always returns 0. Are there other methods that may return the height or does the element have to be a part of the DOM in order for the height to be calculated?

This is a sample of what I'm going for:

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

*Note: This is only a simplified version of the function I'm working on in order to project what I'm trying to achieve without all of the unneeded mess.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

入画浅相思 2024-11-13 19:10:53

在将元素添加到 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 中的空间(因此必须计算它们的大小),但用户实际上无法看到。

Elements don't have a height, in any real sense, until they've been added to the DOM, as their styles cannot be evaluated until then.

You can get around this easily enough using visibility: hidden so that the element can be added to the DOM (and its height determined) without causing visible flickering.

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

(This is working on the assumption that you're using top because the element is absolutely positioned or fixed. If it weren't, you'd need to make it so temporarily.) Hidden elements still take up space in the DOM (so their sizes must be calculated), but cannot actually be seen by the user.

跨年 2024-11-13 19:10:53

如果 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) )

If the height of the DOM node is/can be dynamic then you probably cannot measure it before it exists in the DOM, unless you somehow take into consideration all possible scenarios (font-size, padding/margin/border, actual size, etc.)

A viable option is to inject the node into the DOM, visually hidden, and measure things, and only then reveal it.

Here is a working demo of how to measure an element by briefly adding it to the DOM and inspecting its height, then removing it. This method might be costly since the node is cloned, so the added styles won't affect it afterwards and all DOM events will be removed from it.

If the inspected node has a lot of sub-nodes, this might not be efficient, but stil can be quite handy.

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

追星践月 2024-11-13 19:10:53

在将元素添加到 DOM 之前,我认为这是不可能的,除非您事先知道涉及的所有变量(不太可能)。

然而,可以在它显示在屏幕上之前获取它的高度。

屏幕具有刷新率(每秒显示的最大图像数),因此不可能在 DOM 所做的每次更改时渲染页面。

您可以通过调用 requestAnimationFrame 要求 DOM 在重绘之前通知您。在这里您可以获取元素的属性并更改它们。

您甚至可以通过调用cancelAnimationFrame来取消该帧。

https://developer.mozilla.org/en-US/ docs/Web/API/window/requestAnimationFrame

https ://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame

Before adding the element to the DOM I don't think it is possible, unless you know all the variables involved beforehand (unlikely).

However it is possible to get it's height before it gets displayed on the screen.

The screens have a refresh rate (maximum number of images shown per second) so it is not possible to render the page at each change made by the DOM.

You can ask to the DOM to notify you right before the repaint by calling requestAnimationFrame. Here you can get the element's properties and change them.

You can even cancel this frame by calling cancelAnimationFrame.

https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文