我需要得到一个元素的高度,在一个div是隐藏的。现在我显示div,获得高度,并隐藏父div。这看起来有点傻。有没有更好的办法?

我使用jQuery 1.4.2:

$select.show();
optionHeight = $firstOption.height(); //we can only get height if its visible
$select.hide();

当前回答

下面是我编写的一个脚本,用于处理隐藏元素的所有jQuery维度方法,甚至是隐藏父元素的后代。当然,请注意,使用这种方法会影响性能。

// Correctly calculate dimensions of hidden elements
(function($) {
    var originals = {},
        keys = [
            'width',
            'height',
            'innerWidth',
            'innerHeight',
            'outerWidth',
            'outerHeight',
            'offset',
            'scrollTop',
            'scrollLeft'
        ],
        isVisible = function(el) {
            el = $(el);
            el.data('hidden', []);

            var visible = true,
                parents = el.parents(),
                hiddenData = el.data('hidden');

            if(!el.is(':visible')) {
                visible = false;
                hiddenData[hiddenData.length] = el;
            }

            parents.each(function(i, parent) {
                parent = $(parent);
                if(!parent.is(':visible')) {
                    visible = false;
                    hiddenData[hiddenData.length] = parent;
                }
            });
            return visible;
        };

    $.each(keys, function(i, dimension) {
        originals[dimension] = $.fn[dimension];

        $.fn[dimension] = function(size) {
            var el = $(this[0]);

            if(
                (
                    size !== undefined &&
                    !(
                        (dimension == 'outerHeight' || 
                            dimension == 'outerWidth') &&
                        (size === true || size === false)
                    )
                ) ||
                isVisible(el)
            ) {
                return originals[dimension].call(this, size);
            }

            var hiddenData = el.data('hidden'),
                topHidden = hiddenData[hiddenData.length - 1],
                topHiddenClone = topHidden.clone(true),
                topHiddenDescendants = topHidden.find('*').andSelf(),
                topHiddenCloneDescendants = topHiddenClone.find('*').andSelf(),
                elIndex = topHiddenDescendants.index(el[0]),
                clone = topHiddenCloneDescendants[elIndex],
                ret;

            $.each(hiddenData, function(i, hidden) {
                var index = topHiddenDescendants.index(hidden);
                $(topHiddenCloneDescendants[index]).show();
            });
            topHidden.before(topHiddenClone);

            if(dimension == 'outerHeight' || dimension == 'outerWidth') {
                ret = $(clone)[dimension](size ? true : false);
            } else {
                ret = $(clone)[dimension]();
            }

            topHiddenClone.remove();
            return ret;
        };
    });
})(jQuery);

其他回答

根据定义,元素只有在可见时才有高度。

只是好奇:为什么需要隐藏元素的高度?

一种替代方法是通过将元素放在某种覆盖层的后面(使用z-index)来有效地隐藏元素。

如果你之前已经在页面上显示了元素,你可以直接从DOM元素中获取高度(在jQuery中可以通过.get(0)获得),因为即使在元素隐藏时它也会被设置:

$('.hidden-element').get(0).height;

宽度也一样:

$('.hidden-element').get(0).width;

(感谢Skeets O'Reilly的更正)

一种解决方法是在你想要获取高度的元素外面创建一个父div,应用高度为“0”并隐藏任何溢出。接下来,获取子元素的高度并删除父元素的overflow属性。

Var height = $("#child").height(); //在这里做点什么 $(" #父母”).append(高度).removeClass(“overflow-y-hidden”); .overflow-y-hidden { 高度:0 px; overflow-y:隐藏; } < script src = " https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js " > < /脚本> <div id="parent" class="overflow-y-hidden"> < div id = "孩子" > 这是一些我想要得到高度的内容! < / div > < / div >

实际上,我有时会使用一些技巧来处理这个问题。我开发了一个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();
}

这在很大程度上是可行的,但有一个明显的问题可能会出现。如果要克隆的内容使用CSS样式,其中包含在规则中引用父标记,那么克隆的内容将不包含适当的样式,并且可能具有略微不同的度量。要解决这个问题,您可以确保要克隆的标记应用了CSS规则,这些规则不包括对父标记的引用。

另外,我的滚动部件没有出现这种情况,但是为了获得克隆元素的适当高度,您需要将宽度设置为与父元素相同的宽度。在我的例子中,CSS宽度总是应用于实际的元素,所以我不必担心这一点,但是,如果元素没有应用宽度,您可能需要对元素的DOM祖先进行某种递归遍历,以找到适当的父元素的宽度。

遵循Nick Craver的解决方案,设置元素的可见性可以让它获得准确的尺寸。我经常用这个方法。然而,不得不手动重置样式,我发现这很麻烦,考虑到修改元素的初始位置/显示在我的css通过开发,我经常忘记更新相关的javascript代码。下面的代码不会重置每个say的样式,而是删除javascript添加的内联样式:

$("#myDiv")
.css({
    position:   'absolute',
    visibility: 'hidden',
    display:    'block'
});

optionHeight = $("#myDiv").height();
optionWidth = $("#myDiv").width();

$("#myDiv").attr('style', '');

这里唯一的假设是不能有其他内联样式,否则它们也会被删除。不过,这里的好处是元素的样式将返回到css样式表中的样式。因此,您可以将其写成一个函数,其中传递一个元素,并返回一个高度或宽度。

我发现通过js设置内联样式的另一个问题是,当通过css3处理过渡时,你被迫调整样式规则的权重,使其比内联样式更强,这有时会令人沮丧。