首页 文章

jQuery:在jQuery中获取隐藏元素的高度

提问于
浏览
236

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

我正在使用jQuery 1.4.2:

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

15 回答

  • 1

    你可以做这样的事情,虽然有点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 : "");
    
  • 11

    我遇到了隐藏元素宽度的同样问题,所以我写了这个插件调用jQuery Actual来修复它 . 而不是使用

    $('#some-element').height();
    

    使用

    $('#some-element').actual('height');
    

    会给你隐藏元素的正确值或元素有一个隐藏的父元素 .

    完整文档请看这里 . 页面中还有一个演示包含 .

    希望这有帮助:)

  • 12

    你正在混淆两种CSS样式,display stylevisibility style .

    如果通过设置可见性css样式隐藏元素,那么无论元素是否可见,您都应该能够获得高度,因为元素仍占用页面上的空间 .

    如果通过将显示css样式更改为“none”来隐藏元素,则元素不会在页面上占用空间,并且您必须为其提供显示样式,这将导致元素在某些空间中呈现,哪一点,你可以得到高度 .

  • 172

    我实际上有时会采取一些技巧来解决这个问题 . 我开发了一个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祖先以找到适当的父元素的宽度 .

  • 88

    进一步 Build 尼克的回答:

    $("#myDiv").css({'position':'absolute','visibility':'hidden', 'display':'block'});
    optionHeight = $("#myDiv").height();
    $("#myDiv").css({'position':'static','visibility':'visible', 'display':'none'});
    

    我发现这样做更好:

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

    设置CSS属性会将它们内嵌插入,这将覆盖CSS文件中的任何其他属性 . 通过删除HTML元素上的style属性,一切都恢复正常并仍然隐藏,因为它首先被隐藏 .

  • 1

    进一步构建用户Nick的答案和用户hitautodestruct的JSBin插件,我创建了一个类似的jQuery插件,它检索宽度和高度,并返回包含这些值的对象 .

    它可以在这里找到:http://jsbin.com/ikogez/3/

    更新

    我已经完全重新设计了这个小小的插件,因为事实证明以前的版本(如上所述)在真正的生活环境中并不真正可用,在这些环境中发生了大量的DOM操作 .

    这完美地运作:

    /**
     * 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 <robin@neverwoods.com>
     * @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;
    };
    
  • 38

    您还可以使用负边距将隐藏的div放在屏幕上,而不是使用display:none,就像文本缩进图像替换技术一样 .

    例如 .

    position:absolute;
    left:  -2000px;
    top: 0;
    

    这样高度()仍然可用 .

  • 28

    根据Nick Craver的解决方案,设置元素的可见性可以获得准确的尺寸 . 我经常使用这个解决方案 . 但是,不得不手动重置样式,我发现这很麻烦,因为通过开发修改元素在我的CSS中的初始定位/显示,我经常忘记更新相关的javascript代码 . 以下代码不会重置每个说法的样式,但会删除javascript添加的内联样式:

    $("#myDiv")
    .css({
        position:   'absolute',
        visibility: 'hidden',
        display:    'block'
    });
    
    optionHeight = $("#myDiv").height();
    optionWidth = $("#myDiv").width();
    
    $("#myDiv").attr('style', '');
    

    这里唯一的假设是不能有其他内联样式,否则它们也将被删除 . 然而,这里的好处是元素的样式返回到它们在css样式表中的样式 . 因此,您可以将其编写为元素通过的函数,以及高度或宽度退回 .

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

  • 0

    我试图找到隐藏元素的工作函数,但我意识到CSS比每个人想象的要复杂得多 . CSS3中有许多新的布局技术可能不适用于所有先前的答案,如灵活的框,网格,列或复杂父元素内的元素 .

    flexibox example
    enter image description here

    我认为唯一可持续和简单的解决方案是 real-time rendering . 那时,浏览器应该给你正确的元素大小 .

    遗憾的是,JavaScript在显示或隐藏元素时不提供任何直接事件来通知 . 但是,我创建了一些基于DOM Attribute Modified API的函数,当元素的可见性发生变化时,它将执行回调函数 .

    $('[selector]').onVisibleChanged(function(e, isVisible)
    {
        var realWidth = $('[selector]').width();
        var realHeight = $('[selector]').height();
    
        // render or adjust something
    });
    

    有关更多信息,请访问我的项目GitHub .

    https://github.com/Soul-Master/visible.event.js

    演示:http://jsbin.com/ETiGIre/7

  • 0

    根据定义,元素只有在可见的情况下才具有高度 .

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

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

  • 2

    在我的情况下,我也有一个隐藏的元素阻止我获得高度值,但它不是元素本身,而是它的父母之一...所以我只是检查我的一个插件,看看它是否是隐藏,否则找到最近的隐藏元素 . 这是一个例子:

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

    事实上,这是Nick,Gregory和Eyelidlessness的回应合并给你使用Gregory的改进方法,但是如果你想要放回样式属性中有某些东西,那就使用这两种方法,并寻找父元素 .

    我对解决方案的唯一抱怨是通过父母的循环并不完全有效 .

  • -3

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

    var height = $("#child").height();
    // Do something here
    $("#parent").append(height).removeClass("overflow-y-hidden");
    
    .overflow-y-hidden {
      height: 0px;
      overflow-y: hidden;
    }
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="parent" class="overflow-y-hidden">
      <div id="child">
        This is some content I would like to get the height of!
      </div>
    </div>
    
  • 4

    这是我编写的一个脚本,用于处理隐藏元素的所有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);
    
  • 1

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

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

    宽度相同:

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

    (感谢Skeets O'Reilly的更正)

  • 2
    $('#idOfElement').height();
    

    //找到高度

相关问题