隐藏dom子树时查找元素的高度

时间:2014-05-13 11:40:46

标签: javascript jquery dom height hidden

首先,我已经在SO和其他地方查看了大量相关问题 - 但没有一个问题解决了我的问题(不幸的是)。

我有一个动态构建的DOM子目录,大约10级深度和一个复杂的javascript代码,显示或隐藏该子树(或整个子树)的部分。还有另一个代码可以在该子树内的某处更改各种div元素的文本(某处意味着从1级到10级)。此外,子树内的各个节点也可以显示或隐藏。

总而言之,无论何时更改文本,我都需要弄清楚相应div的新高度。不幸的是,当文本发生变化时,实际的div是"可见"在其父级的上下文中,通常是其父级的父级 - 但不在整个子树的上下文中 - 因此高度返回为0.

几乎所有的解决方案都围绕使div可见,测量其高度,然后再次隐藏它。要对我的问题采用这个解决方案,我将不得不采取有问题的div,然后从它向上遍历dom树,检查相应的父母是否隐藏,改变他们的能见度,继续向上直到我显示所有内容,然后测量我的div的高度,然后恢复我改变的元素的可见性。

除了实施的噩梦之外,它听起来非常缓慢。那么,有没有任何解决方案来获得div的高度,它本身在其父级中是可见的,但隐藏了几个(非直接)父级?我对jQuery或普通的JavaScript解决方案感到满意。

3 个答案:

答案 0 :(得分:1)

如果您不想陷入切换父层次结构可见性的麻烦,那么最好的方法是依赖于 window.getComputedStyle(<elem>)为您提供所需的尺寸。 getComputedStyle的工作方式与元素的可见性状态无关(在撰写本文时至少在FF,Chrome,IE中)

所以在你的情况下,这将是:

var height = window.getComputedStyle(document.getElementById(<id of element in question>)).getPropertyValue("height");

// height would always be in px, except in case of IE where it could be em's depending upon the style usage.
height = parseFloat(height);

答案 1 :(得分:0)

如果您无论如何都不显示该页面上的元素高度,则无法。在您的情况下,如果您说DOM树非常复杂并且元素可能是动态定位的,那么您肯定需要显示所有隐藏的父级和元素本身以获得其大小。操作可能需要很长时间(以毫秒为单位),因此我会为最终用户添加叠加层。

var $overlay = $('<div />').text('loading...').css({
        backgroundColor: '#000',
        position: 'fixed',
        color: '#fff',
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
        zIndex: 100
    }).appendTo('body'),
    $element = $('.element'),
    $parent = $element.parents('.hidden').addClass('shown').show().last(),
    height = $element.height();

$('body').append(height);
$parent.find('.shown').addBack().hide();
$overlay.remove();

我看到的唯一可能的缺点是浏览器可能加载显示的图像,并在计算实际高度后的某个时间更改元素的高度。

DEMO: http://jsfiddle.net/ZuGd7/1/

答案 2 :(得分:0)

我有一个项目,我必须这样做。我已经在这里创建了一个非常基本的工作示例(http://jsbin.com/zujoj/3/),关于如何实现这一点,即使我最终变得更复杂,它基于以下内容:

$(document).ready(function(){

  $("#myButton").on("click", function(){

      // this is a helper variable
      var i = Math.floor(Math.random() * (5 - 1 + 1) + 1);

      // using some dummie text placeholders
      var data = $(".myText" + i).html();

      // this is how I get the height, you see the textContainerStyle? Use yours instead
      var height = $(".textContainerStyle").html(data).height();

      // finally you get the value
      $("#lastHeight").val(height);

  });

});

一些帮助该示例的HTML:

  <input id="lastHeight" type="text" value="0">

  <div class="textContainerStyle">

  </div>

  <ul>
    <li>
      <button id="myButton">Click me</button>
      <div class="hidden myText1"><p>Lorem ipsum colorom dolorem morem</p></div>
      <div class="hidden myText2"><p>Lorem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem</p></div>      
      <div class="hidden myText3"><p>Lorem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem</p></div>
      <div class="hidden myText4"><p>Lorem ipsum</p></div>
      <div class="hidden myText5"><p>Lorem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem. Lorem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem. Lorem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem orem ipsum colorom dolorem morem</p></div>
    </li>
  </ul>

最后,但同样重要的是帮助实现这一目标的风格:

.textContainerStyle {
  padding: 20px;
  position: absolute;
  top: -100%;
  left: -100%;
}
.hidden {
  display: none;
}

希望这对你有所帮助! :)