【问题标题】:Issue recalculating parent height重新计算父高度的问题
【发布时间】:2018-08-10 00:51:38
【问题描述】:

我正在构建一个移动菜单。它分为三个层次。当您单击一个链接时,它会向单击的链接和下一个 ul 添加一个开放类。我通过遍历所有子元素并组合每个元素的高度来计算 ul 的高度。这部分正在工作,我遇到的问题是在计算第二级子级时,我也需要能够重新计算父级 ul,但这需要在计算子级 ul 之后发生,以便获得新的高度。

测试用例:

  1. 单击父级 1

  2. 点击 Child 1(高度不会重新计算)

  3. 点击Parent 1关闭,再次点击(高度现已重新计算)

{
  const primary = document.querySelector(".primary"),
    secondary = document.querySelectorAll(".secondary"),
    children = document.querySelectorAll(".has-children");

  for (let [i, _this] of children.entries()) {
    let currentUL = secondary[i];

    _this.addEventListener("click", e => {
      e.preventDefault();

      // toggle open class
      _this.classList.toggle("open");
      currentUL.classList.toggle("open");

      let children = currentUL.children,
        total = 0;
      for (let x = 0; x < children.length; x++) {
        total = total + children[x].offsetHeight;
      }
      currentUL.classList.contains("open") ?
        (currentUL.style.height = `${total}px`) :
        (currentUL.style.height = 0);
    });
  }
}
.primary {
  max-width: 500px;
  margin: 0 auto;
}

.primary a {
  display: block;
  padding: 20px;
  border-bottom: 1px solid grey;
  font-size: 16px;
  color: green;
}

.secondary {
  height: 0;
  overflow: hidden;
  transition-delay: 0.3s;
  transition: height 0.3s ease;
  margin-left: 38px;
}
<ul class="primary">
  <li>
    <a href="" class="has-children">Parent 1</a>
    <ul class="secondary">
      <li>
        <a href="" class="has-children">Child 1</a>
        <ul class="secondary">
          <li>
            <a href="">1</a>
          </li>
          <li>
            <a href="">2</a>
          </li>
          <li>
            <a href="">3</a>
          </li>
          <li>
            <a href="">4</a>
          </li>
          <li>
            <a href="">5</a>
          </li>
          <li>
            <a href="">6</a>
          </li>
          <li>
            <a href="">7</a>
          </li>
          <li>
            <a href="">8</a>
          </li>
          <li>
            <a href="">9</a>
          </li>
          <li>
            <a href="">10</a>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

【问题讨论】:

    标签: javascript


    【解决方案1】:

    问题是当用户点击文本'Parent 1'时,第一个ul.secondary元素高度被正确更新,但是当用户点击'Child 1'时,第二个ul.secondary高度被正确更新但没有第一个ul.secondary。一个可能的解决方案是,一旦子级发生变化,我在计算父级高度之前使用了 0.3 秒的timeout,因为动画延迟,重新计算父级ul

    要检查我在说什么,您可以使用浏览器的开发工具,选项卡“元素”,然后查看元素的属性style.height 在每次用户交互后如何修改。

    我添加的代码在评论// This is the code I added之后

       
        const primary = document.querySelector(".primary"),
              secondary = document.querySelectorAll(".secondary"),
              children = document.querySelectorAll(".has-children");
    
        for (let [i, _this] of children.entries()) {
            let currentUL = secondary[i];
    
            _this.addEventListener("click", e => {
                e.preventDefault();
    
                // toggle open class
                _this.classList.toggle("open");
                currentUL.classList.toggle("open");
    
                calculateULHeight(currentUL);
    
                 // This is the code I added
                 let parentUL = currentUL.parentElement.parentElement;
    
                if (parentUL.classList.contains('secondary')) {
                    setTimeout(function() {
                        calculateULHeight(parentUL);
                    }, 300);
                }
            });
        }
    
        function calculateULHeight(UL) {
            let children = UL.children,
                total = 0;
       
            for (let x = 0; x < children.length; x++) {
                total = total + children[x].offsetHeight;
            }
    
            UL.classList.contains("open") ?
              (UL.style.height = `${total}px`) :
              (UL.style.height = 0);
        }
    .primary {
      max-width: 500px;
      margin: 0 auto;
    }
    
    .primary a {
      display: block;
      padding: 20px;
      border-bottom: 1px solid grey;
      font-size: 16px;
      color: green;
    }
    
    .secondary {
      height: 0;
      overflow: hidden;
      transition-delay: 0.3s;
      transition: height 0.3s ease;
      margin-left: 38px;
    }
    <ul class="primary">
      <li>
        <a href="" class="has-children">Parent 1</a>
        <ul class="secondary">
          <li>
            <a href="" class="has-children">Child 1</a>
            <ul class="secondary">
              <li>
                <a href="">1</a>
              </li>
              <li>
                <a href="">2</a>
              </li>
              <li>
                <a href="">3</a>
              </li>
              <li>
                <a href="">4</a>
              </li>
              <li>
                <a href="">5</a>
              </li>
              <li>
                <a href="">6</a>
              </li>
              <li>
                <a href="">7</a>
              </li>
              <li>
                <a href="">8</a>
              </li>
              <li>
                <a href="">9</a>
              </li>
              <li>
                <a href="">10</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>

    【讨论】:

    • 谢谢。这不能正确计算父级的高度。
    • @user3486427 我终于让它正常工作了! :) 动画中的延迟让我对高度计算发疯了,这就是为什么我添加了超时,所以计算是在动画完成后完成的。如果有任何帮助,请考虑投票给我的答案,如果您认为有帮助,请将其标记为正确答案。不胜感激,谢谢。
    猜你喜欢
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多