代码之家  ›  专栏  ›  技术社区  ›  Reza Amya

为什么css3转换不使用javascript设置元素的高度?

  •  0
  • Reza Amya  · 技术社区  · 8 年前

    我写了一段代码来创建一个手风琴,你可以看到代码 here .
    有一些HTML代码:

    <div class="accordion_holder">
      <div class="accordion_item">
        <div class="title" onclick="toggle_accordion(this);">
          title 1 here
        </div>
        <div class="content">
          content here
        </div>
      </div>
      <div class="accordion_item">
        <div class="title" onclick="toggle_accordion(this);">
          title 2 here
        </div>
        <div class="content">
          content 2 here
        </div>
      </div>
    </div>
    

    我有下面的css来模拟手风琴的转换:

    .accordion_holder .content {
        height: 0px;
        overflow: hidden;
        -webkit-transition: height 0.5s linear;
        -moz-transition: height 0.5s linear;
        -ms-transition: height 0.5s linear;
        -o-transition: height 0.5s linear;
        transition: height 0.5s linear;
    }
    

    我将内容的高度设置为 0px 或者是 offsetHeight 使用这段javascript代码:

    function toggle_accordion(clicked_element) {
      var father = closest_parent(clicked_element, 'accordion_item');
      console.log(father);
      var accordion_content = father.getElementsByClassName("content")[0];
      var destination = 0;
    
      var current_height = accordion_content.offsetHeight;
    
      if (current_height == 0)
      {
        accordion_content.style.height = "auto";
        destination = accordion_content.offsetHeight;
    
        accordion_content.style.height = "0px";
      }
      console.log("destination is:", destination);
      accordion_content.style.height = destination+"px";
    }
    
    /************************************
     ** Find Closest Parent with Class **
     ***********************************/
    function closest_parent (current_element, class_name) {
        var parent = current_element.parentElement;
        if (parent) {
            if (parent.className.indexOf(class_name) >= 0)
            {
                //We found requested parent
                return parent;
            }
            else
            {
                return closest_parent (parent, class_name);
            }
        }
        else
        {
            return false;
        }
    }
    

    设置内容元素的高度是正确的。关闭时(将内容元素的高度设置为 0px ,移动平稳,过渡效果良好。但是当它打开时(将内容元素的高度设置为 驾驶执照 ),转换将不起作用。
    你能告诉我怎么了吗?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Lucas Bebber    8 年前

    因为你把高度设置为 auto 然后 试图得到它 offsetHeight .

    得到 驾驶执照 triggers a reflow ,因此它已经在布局页面并尝试转换到 height: auto ;因为转换到 高度:汽车 不工作,它会直接跳到目标高度。然后,当您将元素的高度设置为 驾驶执照 ,元素已经具有该高度,因此不会有转换。

    有两种方法可以解决这个问题:

    一种更为老套的方法是将 驾驶执照 对您有利:在将高度设置回0并再次触发回流后,尝试再次获取该值:

    if (current_height == 0)
      {
        accordion_content.style.height = "auto";
        destination = accordion_content.offsetHeight;
    
        accordion_content.style.height = "0px";
        // Here is the trick:
        accordion_content.offsetHeight // triggers a reflow
      }
    

    另一种方法是预先存储手风琴元素内容的高度,因此只需转换到该值。这可能会很棘手,特别是如果手风琴的内容可以改变,但它对深奥的浏览器行为的依赖性会降低。