DOM Element Width before Appended to DOM

后端 未结 6 1713
渐次进展
渐次进展 2020-12-09 02:27

I\'m sure the answer is no, but is it possible to determine the width of an element before it is appended to the DOM?

Once it\'s appended, I know I

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

    Modified the code a bit. Here is a pure JS solution:

    function measure(el, fn) {
        var pV = el.style.visibility, 
            pP = el.style.position;
            
        el.style.visibility = 'hidden';
        el.style.position = 'absolute';
        
        document.body.appendChild(el);
        var result = fn(el);
        el.parentNode.removeChild(el);
        
        el.style.visibility = pV;
        el.style.position = pP;
        return result;
    }
    
    var div = document.createElement('div');
    div.innerHTML = "<p>Hello</p><br/>";
    
    alert(div.offsetHeight); // 0
    
    alert(measure(div, function(el){return el.offsetHeight})); // 68

    0 讨论(0)
  • 2020-12-09 03:08

    It is not possible, at least not accurately, because styling affects these properties, and where it's put determines how it is styled and what rules affect it.

    For example placing a <p></p> in the page would by default be the width of the body if appended as a child to it, but if you appeneded it inside for example a <div style="width: 100px;"></div>, then you see how that quickly changes things.

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

    What you can do with MooTools is use the Element.Measure class - meaning, you inject the element to the DOM, but keep it hidden. Now, you can measure the element without actually showing it.

    http://mootools.net/docs/more/Element/Element.Measure

    0 讨论(0)
  • 2020-12-09 03:14

    The trick is to show the element (display:block) but also hide it (visibility:hidden) and to set it’s position to absolute so that it doesn’t affect the page flow.

    The MooTools Element.Measure class does this, as Oscar mentioned.

    0 讨论(0)
  • 2020-12-09 03:14
    /**
     * Get bounding client rect for an element (not exists at current DOM tree)
     * @param {!HTMLElement} el
     * @return {!Promise<!ClientRect>}
     */
    function getElementRect(el) {
      return new Promise(resolve => {
        const element = el.cloneNode(true);
        element.style.visibility = "hidden";
        element.style.position = "absolute";
        document.body.appendChild(element);
    
        resolve(element.getBoundingClientRect());
        element.remove();
      });
    }
    
    const div = /** @type {!HTMLElement} */ (document.createElement("div"));
    div.innerHTML = "<p>Hello</p><br/>";
    
    // Execute
    (async () => {
      const rect = await getElementRect(div);
      console.log(rect.width);
    })();
    
    

    DEMO

    0 讨论(0)
  • 2020-12-09 03:20

    The Mootools Element.Measure functionality that Oscar mentioned is awesome. For those that use jQuery, here's a quick plugin that accomplishes the same thing:

    $.fn.measure = (fn)->
      el = $(this).clone(false)
      el.css
        visibility: 'hidden'
        position:   'absolute'
      el.appendTo('body')
      result = fn.apply(el)
      el.remove()
      return result
    

    You can call it like this, making sure to return the value (thanks Sam Fen for pointing that out!):

    width = $('.my-class-name').measure( function(){ return this.width() } )
    
    0 讨论(0)
提交回复
热议问题