Find the “potential” width of a hidden element

前端 未结 10 1315
慢半拍i
慢半拍i 2020-12-03 09:31

I\'m currently extending the lavalamp plugin to work on dropdown menus but I\'ve encountered a small problem. I need to know the offsetWidth of an element that

相关标签:
10条回答
  • 2020-12-03 10:08

    What I did was ; by the time hiding that element, stored its width in its dataset. It only will work for you if you can hide programmatically.

    ie.

    When Hiding ;

    var elem = $("selectorOfElement");
    
    elem.dataset.orgWidth = elem.clientWidth;
    

    Later when getting ;

    var elem = $("selectorOfElement");
    
    var originalWidthWas = elem.dataset.orgWidth;
    
    0 讨论(0)
  • 2020-12-03 10:09

    The only thing I can think of is to show it (or a clone of it) to allow retrieval of the offsetWidth.

    For this measurement step, just make its position absolute and its x or y value a big negative, so it will render but not be visible to the user.

    0 讨论(0)
  • 2020-12-03 10:11

    If you know the element to be the full width of a parent element another approach is to create a recursive method:

    es5:

    var getWidth;
    getWidth = function($el){
      return $el.offsetWidth || getWidth($el.parentElement);
    }
    var width = getWidth(document.getElementById('the-element'));
    

    es6:

    let getWidth
    getWidth = ($el) => $el.offsetWidth || getWidth($el.parentElement)
    
    const width = getWidth(document.getElementById('the-element'))
    
    0 讨论(0)
  • 2020-12-03 10:12

    Actual jQuery plugin!

    Usage:

    console.log('width without actual: ' + $('#hidden').width());
    
    console.log('width with actual: ' + $('#hidden').actual('width'));
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.actual/1.0.19/jquery.actual.min.js"></script>
    
    <div style="width: 100px; display: none;">
      <div id="hidden"></div>
    </div>

    0 讨论(0)
  • 2020-12-03 10:13

    You can use the following function to get the outer width of an element that is inside a hidden container.

    $.fn.getHiddenOffsetWidth = function () {
        // save a reference to a cloned element that can be measured
        var $hiddenElement = $(this).clone().appendTo('body');
    
        // calculate the width of the clone
        var width = $hiddenElement.outerWidth();
    
        // remove the clone from the DOM
        $hiddenElement.remove();
    
        return width;
    };
    

    You can change .outerWidth() to .offsetWidth() for your situation.

    The function first clones the element, copying it to a place where it will be visible. It then retrieves the offset width and finally removes the clone. The following snippet illustrates a situation where this function would be perfect:

    <style>
        .container-inner {
            display: none;
        }
    
        .measure-me {
            width: 120px;
        }
    </style>
    
    <div class="container-outer">
        <div class="container-inner">
            <div class="measure-me"></div>
        </div>
    </div>
    

    Please be aware that if there is CSS applied to the element that changes the width of the element that won't be applied if it's a direct descendant of body, then this method won't work. So something like this will mean that the function doesn't work:

    .container-outer .measure-me {
        width: 100px;
    }
    

    You'll either need to:

    • change the specificity of the CSS selector ie. .measure-me { width: 100px; }
    • change the appendTo() to add the clone to a place where your CSS will also be applied to the clone. Ensure that where ever you do put it, that the element will be visible: .appendTo('.container-outer')

    Again, this function assumes that the element is only hidden because it's inside a hidden container. If the element itself is display:none, you can simply add some code to make the clone visible before you retrieve it's offset width. Something like this:

    $.fn.getHiddenOffsetWidth = function () {
        var hiddenElement $(this)
            width = 0;
    
        // make the element measurable
        hiddenElement.show();
    
        // calculate the width of the element
        width = hiddenElement.outerWidth();
    
        // hide the element again
        hiddenElement.hide();
    
        return width;
    }
    

    This would work in a situation like this:

    <style>
        .measure-me {
            display: none;
            width: 120px;
        }
    </style>
    
    <div class="container">
        <div class="measure-me"></div>
    </div>
    
    0 讨论(0)
  • 2020-12-03 10:15

    The width of an element that has CSS visibility: hidden is measurable. It's only when it's display: none that it's not rendered at all. So if it's certain the elements are going to be absolutely-positioned (so they don't cause a layout change when displayed), simply use css('visibility', 'hidden') to hide your element instead of hide() and you should be OK measuring the width.

    Otherwise, yes, show-measure-hide does work.

    0 讨论(0)
提交回复
热议问题