Javascript jQuery:获取 jQuery 中隐藏元素的高度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2345784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery: Get height of hidden element in jQuery
提问by mkoryak
I need to get height of an element that is within a div that is hidden. Right now I show the div, get the height, and hide the parent div. This seems a bit silly. Is there a better way?
我需要获取隐藏的 div 内元素的高度。现在我显示 div,获取高度,并隐藏父 div。这似乎有点傻。有没有更好的办法?
I'm using jQuery 1.4.2:
我正在使用 jQuery 1.4.2:
$select.show();
optionHeight = $firstOption.height(); //we can only get height if its visible
$select.hide();
采纳答案by Nick Craver
You could do something like this, a bit hacky though, forget positionif it's already absolute:
你可以做这样的事情,虽然有点hacky,忘记position它是否已经是绝对的:
var previousCss = $("#myDiv").attr("style");
$("#myDiv").css({
position: 'absolute', // Optional if #myDiv is already absolute
visibility: 'hidden',
display: 'block'
});
optionHeight = $("#myDiv").height();
$("#myDiv").attr("style", previousCss ? previousCss : "");
回答by ben
I ran into the same problem with getting hidden element width, so I wrote this plugin call jQuery Actualto fix it. Instead of using
我在获取隐藏元素宽度时遇到了同样的问题,所以我编写了这个插件调用jQuery Actual来修复它。而不是使用
$('#some-element').height();
use
用
$('#some-element').actual('height');
will give you the right value for hidden element or element has a hidden parent.
将为您提供隐藏元素或元素具有隐藏父元素的正确值。
Full documentation please see here. There is also a demo include in the page.
完整文档请参见此处。页面中还包含一个演示。
Hope this help :)
希望这有帮助:)
回答by casperOne
You are confuising two CSS styles, the display styleand the visibility style.
您混淆了两种 CSS 样式,display style和visible style。
If the element is hidden by setting the visibility css style, then you should be able to get the height regardless of whether or not the element is visible or not as the element still takes space on the page.
如果通过设置可见性 css 样式隐藏元素,那么无论元素是否可见,您都应该能够获取高度,因为该元素仍然占用页面空间。
If the element is hidden by changing the display css style to "none", then the element doesn't take space on the page, and you will have to give it a display style which will cause the element to render in some space, at which point, you can get the height.
如果通过将显示 css 样式更改为“none”来隐藏元素,则该元素不会在页面上占用空间,并且您必须为其指定一个显示样式,这将导致该元素在某个空间中呈现,在哪一点,你可以得到高度。
回答by elliotlarson
I've actually resorted to a bit of trickery to deal with this at times. I developed a jQuery scrollbar widget where I encountered the problem that I don't know ahead of time if the scrollable content is a part of a hidden piece of markup or not. Here's what I did:
我实际上有时会使用一些技巧来处理这个问题。我开发了一个 jQuery 滚动条小部件,在那里我遇到了一个问题,我不知道可滚动内容是否是隐藏标记的一部分。这是我所做的:
// try to grab the height of the elem
if (this.element.height() > 0) {
var scroller_height = this.element.height();
var scroller_width = this.element.width();
// if height is zero, then we're dealing with a hidden element
} else {
var copied_elem = this.element.clone()
.attr("id", false)
.css({visibility:"hidden", display:"block",
position:"absolute"});
$("body").append(copied_elem);
var scroller_height = copied_elem.height();
var scroller_width = copied_elem.width();
copied_elem.remove();
}
This works for the most part, but there's an obvious problem that can potentially come up. If the content you are cloning is styled with CSS that includes references to parent markup in their rules, the cloned content will not contain the appropriate styling, and will likely have slightly different measurements. To get around this, you can make sure that the markup you are cloning has CSS rules applied to it that do not include references to parent markup.
这在大多数情况下是有效的,但可能会出现一个明显的问题。如果您要克隆的内容使用 CSS 设置样式,并在其规则中包含对父标记的引用,则克隆的内容将不包含适当的样式,并且测量值可能略有不同。为了解决这个问题,您可以确保您克隆的标记应用了 CSS 规则,不包括对父标记的引用。
Also, this didn't come up for me with my scroller widget, but to get the appropriate height of the cloned element, you'll need to set the width to the same width of the parent element. In my case, a CSS width was always applied to the actual element, so I didn't have to worry about this, however, if the element doesn't have a width applied to it, you may need to do some kind of recursive traversal of the element's DOM ancestry to find the appropriate parent element's width.
此外,我的滚动小部件也没有出现这种情况,但要获得克隆元素的适当高度,您需要将宽度设置为与父元素相同的宽度。就我而言,CSS 宽度始终应用于实际元素,因此我不必担心这一点,但是,如果元素没有应用于它的宽度,您可能需要执行某种递归遍历元素的 DOM 祖先以找到合适的父元素的宽度。
回答by Robin van Baalen
Building further on user Nick's answer and user hitautodestruct's plugin on JSBin, I've created a similar jQuery plugin which retrieves both width and height and returns an object containing these values.
根据用户 Nick 的回答和 JSBin 上的用户 hitautodestruct 插件,我创建了一个类似的 jQuery 插件,它检索宽度和高度并返回一个包含这些值的对象。
It can be found here:
http://jsbin.com/ikogez/3/
可以在这里找到:http:
//jsbin.com/ikogez/3/
Update
更新
I've completely redesigned this tiny little plugin as it turned out that the previous version (mentioned above) wasn't really usable in real life environments where a lot of DOM manipulation was happening.
我已经完全重新设计了这个小小的插件,因为结果证明以前的版本(上面提到的)在进行大量 DOM 操作的现实生活环境中并不能真正使用。
This is working perfectly:
这是完美的工作:
/**
* getSize plugin
* This plugin can be used to get the width and height from hidden elements in the DOM.
* It can be used on a jQuery element and will retun an object containing the width
* and height of that element.
*
* Discussed at StackOverflow:
* http://stackoverflow.com/a/8839261/1146033
*
* @author Robin van Baalen <[email protected]>
* @version 1.1
*
* CHANGELOG
* 1.0 - Initial release
* 1.1 - Completely revamped internal logic to be compatible with javascript-intense environments
*
* @return {object} The returned object is a native javascript object
* (not jQuery, and therefore not chainable!!) that
* contains the width and height of the given element.
*/
$.fn.getSize = function() {
var $wrap = $("<div />").appendTo($("body"));
$wrap.css({
"position": "absolute !important",
"visibility": "hidden !important",
"display": "block !important"
});
$clone = $(this).clone().appendTo($wrap);
sizes = {
"width": $clone.width(),
"height": $clone.height()
};
$wrap.remove();
return sizes;
};
回答by Gregory Bolkenstijn
Building further on Nick's answer:
进一步建立尼克的回答:
$("#myDiv").css({'position':'absolute','visibility':'hidden', 'display':'block'});
optionHeight = $("#myDiv").height();
$("#myDiv").css({'position':'static','visibility':'visible', 'display':'none'});
I found it's better to do this:
我发现这样做更好:
$("#myDiv").css({'position':'absolute','visibility':'hidden', 'display':'block'});
optionHeight = $("#myDiv").height();
$("#myDiv").removeAttr('style');
Setting CSS attributes will insert them inline, which will overwrite any other attributes you have in your CSS file. By removing the style attribute on the HTML element, everything is back to normal and still hidden, since it was hidden in the first place.
设置 CSS 属性会将它们插入内联,这将覆盖您在 CSS 文件中的任何其他属性。通过删除 HTML 元素上的 style 属性,一切都恢复正常并且仍然隐藏,因为它首先被隐藏了。
回答by vaughanos
You could also position the hidden div off the screen with a negative margin rather than using display:none, much like a the text indent image replacement technique.
您还可以使用负边距将隐藏的 div 放置在屏幕外,而不是使用 display:none,就像文本缩进图像替换技术一样。
eg.
例如。
position:absolute;
left: -2000px;
top: 0;
This way the height() is still available.
这样 height() 仍然可用。
回答by Soul_Master
I try to find working function for hidden element but I realize that CSS is much complex than everyone think. There are a lot of new layout techniques in CSS3 that might not work for all previous answers like flexible box, grid, column or even element inside complex parent element.
我试图找到隐藏元素的工作功能,但我意识到 CSS 比每个人想象的都要复杂。CSS3 中有很多新的布局技术可能不适用于所有以前的答案,例如灵活的框、网格、列甚至复杂父元素中的元素。
flexibox example
弹性盒示例
I think the only sustainable & simple solution is real-time rendering. At that time, browser should give you that correct element size.
我认为唯一可持续且简单的解决方案是实时渲染。那时,浏览器应该给你正确的元素大小。
Sadly, JavaScript does not provide any direct event to notify when element is showed or hidden. However, I create some function based on DOM Attribute Modified API that will execute callback function when visibility of element is changed.
遗憾的是,JavaScript 没有提供任何直接事件来通知元素何时显示或隐藏。但是,我创建了一些基于 DOM 属性修改 API 的函数,该函数将在元素可见性改变时执行回调函数。
$('[selector]').onVisibleChanged(function(e, isVisible)
{
var realWidth = $('[selector]').width();
var realHeight = $('[selector]').height();
// render or adjust something
});
For more information, Please visit at my project GitHub.
有关更多信息,请访问我的项目 GitHub。
https://github.com/Soul-Master/visible.event.js
https://github.com/Soul-Master/visible.event.js
回答by Prusprus
Following Nick Craver's solution, setting the element's visibility allows it to get accurate dimensions. I've used this solution very very often. However, having to reset the styles manually, I've come to find this cumbersome, given that modifying the element's initial positioning/display in my css through development, I often forget to update the related javascript code. The following code doesn't reset the styles per say, but removes the inline styles added by javascript:
按照 Nick Craver 的解决方案,设置元素的可见性使其能够获得准确的尺寸。我经常使用这个解决方案。然而,不得不手动重置样式,我发现这很麻烦,因为通过开发修改元素在我的css中的初始定位/显示,我经常忘记更新相关的javascript代码。以下代码不会重置样式,而是删除由 javascript 添加的内联样式:
$("#myDiv")
.css({
position: 'absolute',
visibility: 'hidden',
display: 'block'
});
optionHeight = $("#myDiv").height();
optionWidth = $("#myDiv").width();
$("#myDiv").attr('style', '');
The only assumption here is that there can't be other inline styles or else they will be removed aswell. The benefit here, however, is that the element's styles are returned to what they were in the css stylesheet. As a consequence, you can write this up as a function where an element is passed through, and a height or width is returned.
这里唯一的假设是不能有其他内联样式,否则它们也会被删除。然而,这里的好处是元素的样式返回到它们在 css 样式表中的样式。因此,您可以将其写成一个函数,其中传递一个元素,并返回一个高度或宽度。
Another issue I've found of setting the styles inline via js is that when dealing with transitions through css3, you become forced to adapt your style rules' weights to be stronger than an inline style, which can be frustrating sometimes.
我发现通过 js 设置内联样式的另一个问题是,在通过 css3 处理过渡时,您被迫调整样式规则的权重以使其比内联样式更强,这有时会令人沮丧。
回答by marksyzm
In my circumstance I also had a hidden element stopping me from getting the height value, but it wasn't the element itself but rather one of it's parents... so I just put in a check for one of my plugins to see if it's hidden, else find the closest hidden element. Here's an example:
在我的情况下,我也有一个隐藏元素阻止我获取高度值,但这不是元素本身,而是它的父元素之一......所以我只是检查了我的一个插件,看看它是否是隐藏,否则找到最近的隐藏元素。下面是一个例子:
var $content = $('.content'),
contentHeight = $content.height(),
contentWidth = $content.width(),
$closestHidden,
styleAttrValue,
limit = 20; //failsafe
if (!contentHeight) {
$closestHidden = $content;
//if the main element itself isn't hidden then roll through the parents
if ($closestHidden.css('display') !== 'none') {
while ($closestHidden.css('display') !== 'none' && $closestHidden.size() && limit) {
$closestHidden = $closestHidden.parent().closest(':hidden');
limit--;
}
}
styleAttrValue = $closestHidden.attr('style');
$closestHidden.css({
position: 'absolute',
visibility: 'hidden',
display: 'block'
});
contentHeight = $content.height();
contentWidth = $content.width();
if (styleAttrValue) {
$closestHidden.attr('style',styleAttrValue);
} else {
$closestHidden.removeAttr('style');
}
}
In fact, this is an amalgamation of Nick, Gregory and Eyelidlessness's responses to give you the use of Gregory's improved method, but utilises both methods in case there is supposed to be something in the style attribute that you want to put back, and looks for a parent element.
事实上,这是 Nick、Gregory 和 Eyelidless 的反应的合并,为您提供使用 Gregory 改进方法的方法,但同时使用这两种方法,以防您想要放回 style 属性中的某些内容,并查找一个父元素。
My only gripe with my solution is that the loop through the parents isn't entirely efficient.
我对我的解决方案唯一的抱怨是通过父母的循环并不完全有效。

