你如何找到"显示的尺寸:无"元件?

时间:2016-02-20 04:31:39

标签: javascript html css

我在div中有一些子元素,它们会应用CSS display: none,我想知道子元素的维度是什么。我怎么能这样做?

Fiddle Demo



var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';

#some-hidden-div{
  display: none;
}
.whats-my-dims{
  width: 69px;
  height: 42px;
  background-color: #f00;
}

<div id='output'>Processing... :p</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'></div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>
&#13;
&#13;
&#13;

我只能使用纯JavaScript(没有jQuery)。

我无法更改top / left / right / bottom / transform / translate / etc,因为这将成为可以包含子元素的动画精灵表自定义组件的一部分。

6 个答案:

答案 0 :(得分:8)

您无法使用display: none找到元素的尺寸,但您可以打开显示,获取尺寸,然后将其重新设置为隐藏。这不会造成任何视觉差异。

&#13;
&#13;
var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var someHiddenDiv = document.querySelector('#some-hidden-div');
someHiddenDiv.style.display = 'block';
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
someHiddenDiv.style.display = 'none';
&#13;
#some-hidden-div {
  display: none;
}
.whats-my-dims {
  width: 75px;
  height: 42px;
  background-color: #f00;
}
&#13;
<div id='output'>
  Processing... :p
</div>
<div>
  Sooo... How do I get the width and height of whats-my-dims1?
</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'></div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>
&#13;
&#13;
&#13;

请注意,在某些情况下,使用内联样式设置display: none可能会导致不必要的麻烦(因为内联样式优先于CSS选择器,除非它们具有!important)。在这种情况下,您可能希望完全删除样式属性。

在下面的代码段中,您会看到添加.show类无效,因为内联display: none优先。

&#13;
&#13;
var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var someHiddenDiv = document.querySelector('#some-hidden-div');
someHiddenDiv.style.display = 'block';
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
someHiddenDiv.style.display = 'none';


var btn = document.querySelector('#show');

btn.addEventListener('click', function() {
  someHiddenDiv.classList.add('show');
});
&#13;
#some-hidden-div {
  display: none;
}
.whats-my-dims {
  width: 75px;
  height: 42px;
  background-color: #f00;
}
#some-hidden-div.show {
  display: block;
}
&#13;
<div id='output'>
  Processing... :p
</div>
<div>
  Sooo... How do I get the width and height of whats-my-dims1?
</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'>Some text</div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>

<button id='show'>Show the hidden div</button>
&#13;
&#13;
&#13;

而在下面的代码段中,它不会导致任何问题,因为内联样式已完全删除。

&#13;
&#13;
var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var someHiddenDiv = document.querySelector('#some-hidden-div');
someHiddenDiv.style.display = 'block';
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
someHiddenDiv.style = null;


var btn = document.querySelector('#show');

btn.addEventListener('click', function() {
  someHiddenDiv.classList.add('show');
});
&#13;
#some-hidden-div {
  display: none;
}
.whats-my-dims {
  width: 75px;
  height: 42px;
  background-color: #f00;
}
#some-hidden-div.show {
  display: block;
}
&#13;
<div id='output'>
  Processing... :p
</div>
<div>
  Sooo... How do I get the width and height of whats-my-dims1?
</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'>Some text</div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>

<button id='show'>Show the hidden div</button>
&#13;
&#13;
&#13;

答案 1 :(得分:7)

使用window.getComputedStyle()

var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + window.getComputedStyle(wmd1).getPropertyValue("width") 
+ '", "' 
+ window.getComputedStyle(wmd1).getPropertyValue("height") 
+ '", wmd2: "' 
+ window.getComputedStyle(wmd2).getPropertyValue("width") + '", "' 
+ window.getComputedStyle(wmd2).getPropertyValue("height") + '"';
#some-hidden-div{
  display: none;
}
.whats-my-dims{
  display:block;
  width: 69px;
  height: 42px;
  background-color: #f00;
}
<div id='output'>
  Processing... :p
</div>
<div>
  Sooo... How do I get the width and height of whats-my-dims1?
</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'></div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>

jsfiddle https://jsfiddle.net/h9b17vyk/3/

答案 2 :(得分:6)

您无法使用display: none获取元素的维度,因为它隐藏了,它不占用任何空间,因此它没有维度。这同样适用于其子女。

您可以将元素显示一段时间,检查子尺寸并使元素不可见。正如@JanDvorak指出的那样:

  

浏览器在同步Javascript运行时不会重新绘制,因此该元素永远不会出现在屏幕上。

示例代码:

var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var wmd2 = document.getElementById('whats-my-dims2');
var hiddenDiv = document.getElementById("some-hidden-div");
hiddenDiv.style.display = "block";
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
hiddenDiv.style.display = "";

请参阅demo on JS Fiddle

答案 3 :(得分:1)

您可以添加:

var wmd1Style = window.getComputedStyle(wmd1);
o.innerHTML = 'wmd1: "' + parseInt(wmd1Style['width'], 10) + '", "' + parseInt(wmd1Style['height'], 10) + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';

答案 4 :(得分:1)

对于需要使用此菜单来实现上下文菜单或提示窗口的人:

getComputedStyle()似乎不适用于具有动态宽度/高度的元素。您得到的只是auto

我的方法是设置visibility: hidden并设置display以外的none(显示元素需要什么)。

我在上下文菜单组件中使用了此三步方法来计算相对于单击位置的菜单始终放置在屏幕上的位置:

  1. 设置visibility: hidden并删除display: none(设置为最终显示菜单时的状态)
  2. 获取尺寸
  3. 删除visibility: hidden

当父级也有display: none时,它仍然可能无法正常工作,但这不是该用例的问题,因为一个人不能(不应)访问一个始终未显示的对象的上下文菜单

答案 5 :(得分:0)

出于某种原因,我使用的方法可以工作,但是,有趣的是,我无法正确解释原因。基本上,在我的用例中,我需要知道选项卡的高度,以便在普通js中顺利切换它们。

要计算高度,我在javascript中执行以下步骤:

  1. 已显示元素,但带有“ height:0px”和“ overflow:hidden”(替代“ display:none”)
  2. 将元素设置为“ height:auto”
  3. 使用offsetHeight属性计算元素的高度
  4. 将元素设置回“ height:0px”
  5. 将计算出的高度设置为setTimeout内的元素,并结合css过渡以实现更平滑的过渡

我希望动画会闪烁,但不会。能够做到这一点让我感到震惊,因为它可能是这里的最简单的解决方案,但是如果您了解它的工作原理并且看到这样做的缺点,可以随时分享您的想法。

  function toggleTabs() {
    let tabs = document.querySelectorAll('.accordionX a span')
    tabs.forEach(tab => {
      tab.addEventListener('click', function(e) {
        tab.classList.toggle('active')
        if (tab.classList.contains('active')) {
          //hide other tabs
          tabs.forEach(tab => {
            if (tab != e.target) {
              tab.classList.remove('active');
              tab.parentElement.nextElementSibling.style.height = '0px';
            }
          })
          var tabContent = tab.parentElement.nextElementSibling;
          tabContent.style.height = 'auto';
          var tabHeight = tabContent.offsetHeight + 'px'
          tabContent.style.height = '0px';
          setTimeout(function() {tabContent.style.height = tabHeight}, 15)
        } else {
          tab.classList.remove('active');
          tab.parentElement.nextElementSibling.style.height = '0px';
        }
      })
    })
  } toggleTabs();
.accordionX{margin:0px 20px}
.accordionX > li{border-bottom:1px solid #e7e7e7;position:relative;list-style-type:none}
.accordionX > li:first-child{border-top:1px solid #e7e7e7}
.accordionX > li a::after{display:none}
.accordionX > li p{color:#3c3c3b;line-height:1.8;text-align:left}
.accordionX > li > a span{position:relative;color:#3c3c3b;padding-right:5%;display:block;cursor:pointer;font-weight:600;line-height:3;text-indent:15px;user-select:none;-webkit-tap-highlight-color:transparent;border:none!important}
.accordionX > li > a span:after{width:8px;height:8px;border-right:1px solid #3c3c3b;border-bottom:1px solid #3c3c3b;position:absolute;right:18px;top:25px;content:" ";top:50%;transform:translate(0,-50%) rotate(-45deg);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}
.accordionX > li > a span > img {vertical-align: middle;margin-right: 10px;}
.accordionX p{font-size:1em;padding:10px 15px 0}
.accordionX > li > a span.active:after{transform:translate(0,-75%) rotate(45deg);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}
.accordionX .in-accordion{box-sizing:content-box;overflow:hidden;height:0px;transition:height .4s ease 0.1s}
.accordionX .in-accordion li {list-style: disc;list-style-position: inside;}
.accordionX .in-accordion p:last-child{padding-bottom:20px}
<ul class="accordionX">
    <li>
        <a id="tab1">
            <span>TAB 1</span>
        </a>
        <div class="in-accordion" style="height: 0px;">
            <p>
                Lorem ipsum dolor sit amet consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia.
            </p>
        </div>
    </li>

    <li>
        <a id="tab2">
            <span>TAB 2</span>
        </a>
        <div class="in-accordion" style="height: 0px;">
            <p>
                Lorem ipsum dolor sit amet consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia. Lorem ipsum dolor sit
                amet consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia. Lorem ipsum dolor sit amet
                consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia.
            </p>
        </div>
    </li>
</ul>