【问题标题】:Find the "potential" width of a hidden element找到隐藏元素的“潜在”宽度
【发布时间】:2009-12-03 16:30:05
【问题描述】:

我目前正在扩展lavalamp plugin 以处理下拉菜单,但我遇到了一个小问题。我需要知道隐藏元素的offsetWidth。现在显然这个问题没有意义,而我正在寻找的是元素的offsetWidth,如果它没有隐藏的话。

解决方案是显示它,抓住宽度,然后再次隐藏?一定有更好的办法……

【问题讨论】:

    标签: javascript jquery css


    【解决方案1】:

    具有 CSS visibility: hidden 的元素的宽度是可测量的。只有当它是 display: none 时,它才不会被渲染。因此,如果确定元素将被绝对定位(因此它们在显示时不会导致布局更改),只需使用css('visibility', 'hidden') 来隐藏您的元素而不是hide(),您应该可以测量宽度。

    否则,是的,show-measure-hide 确实有效。

    【讨论】:

      【解决方案2】:

      我唯一能想到的就是显示它(或它的克隆)以允许检索 offsetWidth。

      对于此测量步骤,只需将其位置设为绝对值,并将其 x 或 y 值设为大负数,这样它就会呈现但对用户不可见。

      【讨论】:

      • 这里有一篇关于这个主题的博文。此方法可能遇到的一个问题是将位置重置回原始值。在这种情况下使用交换方法效果很好。 bit.ly/6KwGzm
      • 如果您正在克隆元素,则无需将其重置回原来的位置。取回其位置后,只需删除克隆即可。
      【解决方案3】:

      您可以使用以下函数来获取隐藏容器内的元素的外部宽度

      $.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;
      };
      

      您可以根据自己的情况将.outerWidth() 更改为.offsetWidth()

      该函数首先克隆元素,将其复制到可见的地方。然后它检索偏移宽度并最终删除克隆。下面的 sn-p 说明了这个函数将是完美的情况:

      <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>
      

      请注意,如果对元素应用了 CSS 来改变元素的宽度,而如果它是 body 的直接后代则不会应用,那么此方法将不起作用。所以这样的事情将意味着该功能不起作用:

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

      您需要:

      • 更改 CSS 选择器的特殊性,即。 .measure-me { width: 100px; }
      • 更改appendTo() 以将克隆添加到您的CSS 也将应用于克隆的位置。确保无论你把它放在哪里,该元素都是可见的:.appendTo('.container-outer')

      同样,这个函数假设元素是隐藏的,因为它在一个隐藏的容器中。如果元素本身是display:none,您可以简单地添加一些代码以使克隆可见,然后再检索它的偏移宽度。像这样的:

      $.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;
      }
      

      这适用于这样的情况:

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

      【讨论】:

      • 很有趣,但它不适用于任何类型的样式继承或容器指定的样式。
      • 是的,正如我在回答中提到的那样。有一些建议可以解决这个问题,但我同意,它并不完美。
      【解决方案4】:

      两种选择:

      1. 将元素定位在视口之外(例如:left:-10000px
      2. 使用visibility: hiddenopacity: 0 而不是hide()

      无论哪种方式都可以隐藏元素,但仍然可以获得计算出的宽度。在 thi 上使用 Safari 时要小心,它非常快,有时甚至太快...

      【讨论】:

        【解决方案5】:

        Actual jQuery plugin!

        用法:

        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>

        【讨论】:

          【解决方案6】:

          如果您知道元素是父元素的全宽,另一种方法是创建递归方法:

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

          【讨论】:

            【解决方案7】:

            我所做的是; 在隐藏该元素时,将其宽度存储在其数据集中。 只有当您可以通过编程方式隐藏时,它才会对您有用。

            即。

            隐藏时;

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

            以后获取时;

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

            【讨论】:

              【解决方案8】:

              那是因为它通过 display: none;我过去所做的是制作一个“接收器” div,我使用绝对定位将其从页面上移开。然后我将新元素加载到其中,抓取尺寸,然后在我完成后将其移除 - 然后在我完成后移除接收器。

              您可以做的另一件事是不使用 hide();但改为设置可见性:隐藏;展示: ;然而,这意味着无论节点连接到哪里都会呈现空白区域。

              【讨论】:

                【解决方案9】:
                 var $hiddenElement = $('#id_of_your_item').clone().css({ left: -10000, top: -10000, position: 'absolute', display: 'inline', visibility: 'visible' }).appendTo('body');
                 var width = parseInt($hiddenElement.outerWidth());
                 $hiddenElement.remove();
                

                【讨论】:

                  【解决方案10】:

                  我试图找到隐藏元素的工作函数,但我意识到 CSS 比大家想象的要复杂得多。 CSS3 中有许多新的布局技术可能不适用于所有以前的答案,例如灵活的框、网格、列甚至复杂父元素内的元素。

                  flexibox 示例

                  我认为唯一可持续且简单的解决方案是实时渲染。那时,浏览器应该为您提供正确的元素大小

                  遗憾的是,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

                  【讨论】:

                    【解决方案11】:

                    抱歉,这次谈话我迟到了。我很惊讶没有人提到getComputedStyle。 (请注意,这仅在 CSS 设置宽度值时才有效) 抢元素:
                    let yourEle = document.getElementById('this-ele-id');

                    并使用函数:
                    getComputedStyle(yourEle).width

                    这将返回一个字符串,因此您必须从字符串中删除数字。 即使元素的显示样式设置为none,这也有效。

                    其他要阅读的文章包括zellwk.com

                    【讨论】:

                      猜你喜欢
                      • 2015-09-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-04-01
                      • 1970-01-01
                      • 2020-10-16
                      • 1970-01-01
                      • 2012-03-03
                      相关资源
                      最近更新 更多