【问题标题】:Always push content down when changing a div's height without changing the page position在不改变页面位置的情况下更改 div 的高度时始终下推内容
【发布时间】:2020-12-08 09:44:54
【问题描述】:

我有一个页面,内容中间有一个div,它的高度可以从javascript改变。

当 div 高度发生变化时,如何控制页面滚动的方式?我希望内容总是被向下推,而不是向上。

目前,内容会被向下或向上推送,具体取决于单击按钮时页面滚动的位置。

这是一个最小的例子:

function toggle(ev) {
    const div = document.querySelector("div");
    if (div.style.height === "336px") {
      div.style.height = "147px";
    } else {
        div.style.height = "336px";
    }
}
body {max-width: 60em; margin: auto;}
<p style="background-color: coral; height: 400px;"></p>
<div style="background-color:grey; height: 147px;"></div>
<button href="#" onclick="toggle()">toggle div size</button>
<p style="background-color: olive; height: 3000px;"></p>

为了让事情更清楚,我正在寻找一种解决方案,即当 div 展开时,无论按钮当前在窗口的哪个位置,顶部段落都不会移动。即底部段落应该像按钮一样向上/向下移动。

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    在更新内容高度之前尝试模糊元素(点击处理程序上的 e.target.blur())使其处于非活动状态。由于窗口不再认为该按钮处于活动状态,因此它将不再滚动页面以使其保持可见。

    const handleClick = e => {
        e.target.blur()
        updateScrollHeight()
    }
    

    function toggle(ev) {
        const div = document.querySelector("div");
        ev.target.blur();
        if (div.style.height === "336px") {
          div.style.height = "147px";
        } else {
            div.style.height = "336px";
        }
    }
    
    document.querySelector("button").addEventListener("click", toggle);
    body {max-width: 60em; margin: auto;}
    <p style="background-color: coral; height: 400px;"></p>
    <div style="background-color:grey; height: 147px;"></div>
    <button href="#">toggle div size</button>
    <p style="background-color: olive; height: 3000px;"></p>

    【讨论】:

      【解决方案2】:

      如果我理解正确,您每次设置高度时都希望在底部滚动

      function toggle(ev) {
        const div = document.querySelector("div");
        if (div.style.height === "336px") {
          div.style.height = "147px";
        } else {
            div.style.height = "336px";
        }
        div.scrollTop = div.scrollHeight
      }
      

      【讨论】:

      • 不,我不想滚动页面和 div。
      【解决方案3】:

      您可以使用window.scrollTo 函数滚动到选定的元素。

      <!doctype html>
      
      <style>
          body {max-width: 60em; margin: auto;}
      </style>
      
      <script>
      function toggle(ev) {
          const div = document.querySelector("div");
          if (div.style.height === "336px") {
            div.style.height = "147px";
          } else {
              div.style.height = "336px";
          }
          window.scrollTo(0, div.scrollHeight);
      }
      </script>
      
      <p style="background-color: coral; height: 400px;"></p>
      <div style="background-color:grey; height: 147px;"></div>
      <button href="#" onclick="toggle()">toggle div size</button>
      <p style="background-color: olive; height: 3000px;"></p>

      【讨论】:

      • 不,我不想滚动页面。如果顶部段落已经在视图中,则根本不应该移动。
      【解决方案4】:

      页面将当前活动元素保持在视图中 - 即您单击的按钮 - 因此额外的高度将根据按钮相对于屏幕的位置向上或向下移动。

      您要做的是使页面看起来在元素展开后没有向上滚动。为此,我们只需将页面滚动回到元素展开之前的位置 - 这使它看起来好像高度向下展开了。

      1.保存页面顶部的当前位置

      var pagePosBeforeExpand = window.pageYOffset;
      

      2。如果 div 已展开,则将页面滚动回更改高度之前的位置:

      // if we are increasing the height, then scroll to the previous top...
      window.scrollTo({ top: pagePosBeforeExpand });
      

      请注意,这不会影响您再次折叠高度时,因为您没有在问题中要求这样做,但是您可以调整它以适应这种情况 - 例如您可以简单地移动滚动代码以在 if 之外执行。

      工作示例:

      function toggle(ev) {
          // 1. Save the current position of the top of the page
          var pagePosBeforeExpand = window.pageYOffset;
      
          const div = document.querySelector("div");
          if (div.style.height === "336px") {
            div.style.height = "147px";
          } else {
              div.style.height = "336px";
              // 2. scroll the page back to the position it was beforewe changed the height
              window.scrollTo({ top: pagePosBeforeExpand })
          }
      }
      body {max-width: 60em; margin: auto;}
      <p style="background-color: coral; height: 400px;"></p>
      <div style="background-color:grey; height: 147px;">Top of content</div>
      <button href="#" onclick="toggle()">toggle div size</button>
      <p style="background-color: olive; height: 3000px;"></p>

      【讨论】:

      • 这不是我正在寻找的解决方案,因为它会移动整个页面。我想要的行为与我的示例相同,即使按钮靠近窗口顶部也是如此。即最上面的段落不应该移动。
      • @fouronnes 我误解了你想要做什么,但是我的答案中的解释仍然准确,所以我们知道发生了什么,我会编辑答案以按照你需要的方式工作
      • 仍然不是我想要的。我希望当 div 高度改变底部段落和按钮移动时,而不是顶部段落。
      • @fouronnes 在您之前检查时我没有更新我的答案。从那以后,我已经更新了我的答案,它可以按照您想要的方式工作 - 如果您将 sn-p 扩展到整页,您可以看到它。默认操作是页面滚动,因此按钮不会移动,因此您需要将页面滚动回您想要的位置,这是执行此操作的方法:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      相关资源
      最近更新 更多