如何在调整大小时保持用户的滚动位置 div

How to keep user's scrolling place when resizing div

我想为我正在处理的网站做一个很酷的菜单效果。我有一个 div 作为主要内容的部分。当用户打开菜单时,主要内容 div 将调整大小并移开,显示菜单。但是,当我使用我编写的代码执行此操作时,它总是会丢失我在页面上的滚动位置。有什么办法可以在页面缩小和再次展开时保持我在页面上的位置?以下是我所拥有的。提前致谢!

function shrinkPage() {
   
   var element = document.getElementById("mock-body");
   element.classList.toggle("mock-body-on-burger");
   
   var z = document.getElementById("mock-body-container");
   z.classList.toggle("mock-body-container-on-burger");
   
   var x = document.getElementById("body");
   x.classList.toggle("body-on-burger");
};
body {
 margin: 0;
 background:#000;
}

.body-on-burger {
 max-width: 100%;
 overflow-x:hidden;
}

.mock-body-container{
 height:100vh;
}

.mock-body-container-on-burger {
 height:100vh;
 transform: scale(0.4) translate(130%);
 overflow: hidden;
}

.mock-body-size-change{
 overflow: scroll;
}

.mock-body {
 position:relative;
 background: #fff;
 margin-left: 50px;
}
  
.container {
 position: fixed;
 height:50px;
 width:50px;
 cursor: pointer;
}

.container #icon {
 width: 16px;
 height: 8px;
 position: relative;
 margin: 0px auto 0;
 top: 40%;
}

.container #icon .bars {
 height: 1px;
 background: #fff;
}

.myDiv {
 height:500px;
}

.one {
 background:red;
}

.two {
 background:green;
}

.three {
 background:blue;
}
<body id="body">



 <div class="menu-activator" onclick="shrinkPage()">
  <div class="container usd">
   <div id="icon">
    <div class="bars first"></div>
   </div>
  </div>
 </div>
 
 
 <div id="mock-body-container" class="mock-body-container">
  <div id="mock-body" class="mock-body">
   <div class="myDiv one"></div>
   <div class="myDiv two"></div>
   <div class="myDiv three"></div>
  </div>
  </div>
   </body>

一旦您知道焦点所在的元素,它应该相对容易。如果您需要查找最后获得焦点的元素,可以使用 scroll 函数来实现。如果您也需要这个,请告诉我,我会更新我的答案。

如果您知道 #mock-body 是焦点中的最后一个元素,只需在调整大小后滚动回到它即可。

在此示例中,我使用了 jQuery,因为它使这种交互更容易,但这也可以使用 vanilla JS 来完成(尽管更冗长)。

$('html, body').animate({
  scrollTop: $('#mock-body').offset().top
}, 0); // If you want the animation to be smoother you can increase 0 to a higher number

请看下面的代码片段。注意 overflow 属性 是如何使用的。

您必须滚动 mock-body-container 才能保持其滚动位置。 您正在滚动 body,因此当您缩放 mock-body-container 时,body 中没有任何内容可滚动并且您松开滚动位置。

function shrinkPage() {
   
   var element = document.getElementById("mock-body");
   element.classList.toggle("mock-body-on-burger");
   
   var z = document.getElementById("mock-body-container");
   z.classList.toggle("mock-body-container-on-burger");
   
   var x = document.getElementById("body");
   x.classList.toggle("body-on-burger");
};
body {
 margin: 0;
 background:#000;
}

.body-on-burger {
 max-width: 100%;
 overflow-x:hidden;
}

.mock-body-container{
 height:100vh;
  overflow:auto;
}

.mock-body-container-on-burger {
 height:100vh;
 transform: scale(0.4) translate(130%);
}

.mock-body-size-change{
 overflow: scroll;
}

.mock-body {
 position:relative;
 background: #fff;
 margin-left: 50px;
}
  
.container {
 position: fixed;
 height:50px;
 width:50px;
 cursor: pointer;
}

.container #icon {
 width: 16px;
 height: 8px;
 position: relative;
 margin: 0px auto 0;
 top: 40%;
}

.container #icon .bars {
 height: 1px;
 background: #fff;
}

.myDiv {
 height:500px;
}

.one {
 background:red;
}

.two {
 background:green;
}

.three {
 background:blue;
}
<body id="body">



 <div class="menu-activator" onclick="shrinkPage()">
  <div class="container usd">
   <div id="icon">
    <div class="bars first"></div>
   </div>
  </div>
 </div>
 
 
 <div id="mock-body-container" class="mock-body-container">
  <div id="mock-body" class="mock-body">
   <div class="myDiv one"></div>
   <div class="myDiv two"></div>
   <div class="myDiv three"></div>
  </div>
  </div>
   </body>

一个简单的方法是记住文档滚动的位置,并在您返回 "normal" 视图时重新应用它:

let savedScroll; 

function shrinkPage() {
  let _s = (el) => document.querySelector(el),
      s_ = (d) => !d.classList.contains('body-on-burger'),
    x = _s('#body'),
    element = _s('#mock-body'),
    z = _s('#mock-body-container');

  if (s_(x)) {
    savedScroll = document.documentElement.scrollTop;
  }

  element.classList.toggle("mock-body-on-burger");
  z.classList.toggle("mock-body-container-on-burger");
  x.classList.toggle("body-on-burger");

  if (s_(x)) {
    document.documentElement.scrollTop = savedScroll;
  }
};

查看:

let savedScroll; 

function shrinkPage() {
  let _s = (el) => document.querySelector(el),
      s_ = (d) => !d.classList.contains('body-on-burger'),
    x = _s('#body'),
    element = _s('#mock-body'),
    z = _s('#mock-body-container');

  if (s_(x)) {
    savedScroll = document.documentElement.scrollTop;
  }

  element.classList.toggle("mock-body-on-burger");
  z.classList.toggle("mock-body-container-on-burger");
  x.classList.toggle("body-on-burger");

  if (s_(x)) {
    document.documentElement.scrollTop = savedScroll;
  }
};
body {
  margin: 0;
  background: #000;
}

.body-on-burger {
  max-width: 100%;
  overflow-x: hidden;
}

.mock-body-container {
  height: 100vh;
}

.mock-body-container-on-burger {
  height: 100vh;
  transform: scale(0.4) translate(130%);
  overflow: hidden;
}

.mock-body-size-change {
  overflow: scroll;
}

.mock-body {
  position: relative;
  background: #fff;
  margin-left: 50px;
}

.container {
  position: fixed;
  height: 50px;
  width: 50px;
  cursor: pointer;
}

.container #icon {
  width: 16px;
  height: 8px;
  position: relative;
  margin: 0px auto 0;
  top: 40%;
}

.container #icon .bars {
  height: 1px;
  background: #fff;
}

.myDiv {
  height: 500px;
}

.one {
  background: red;
}

.two {
  background: green;
}

.three {
  background: blue;
}
<body id="body">
  <div class="menu-activator" onclick="shrinkPage()">
    <div class="container usd">
      <div id="icon">
        <div class="bars first"></div>
      </div>
    </div>
  </div>


  <div id="mock-body-container" class="mock-body-container">
    <div id="mock-body" class="mock-body">
      <div class="myDiv one"></div>
      <div class="myDiv two"></div>
      <div class="myDiv three"></div>
    </div>
  </div>
</body>

图例:_s(el) returns els_(d) 的第一场比赛检查 d 是否有 class body-on-burger

执行此操作的简单方法是确定调整大小期间高度的变化,然后滚动那么多。

const heightChange = newHeight - initialHeight;
scrollableDiv.scrollTop = scrollableDiv.scrollTop - heightChange;

在我的例子中,我使用的是我编写的调整大小方法,所以当我知道 div 正在被用户主动调整大小时,我在 window.addEventListener("mousemove", handleResize); 中完成这项工作。

这仍然适用于原生 html 可调整大小的元素,您只需要弄清楚 how/when 相应地监听 resize/drag 事件。