ScrollIntoView 打破溢出滚动

ScrollIntoView breaks the overflow scroll

我有一个嵌套的子容器,当我尝试 scrollIntoView 它破坏了父容器。我不明白为什么它会这样。请帮我解决这个问题。
请查看下面或 jsfiddle

上的代码

function moveToTop() {
  console.log('MOVE TO TOP::');
  const child = document.getElementById('child');
  child.scrollIntoView({
    behavior: "smooth"
  });
}
#parent {
  background-color: blue;
  padding: 10px;
  height: 500px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

#scroller {
  overflow: auto;
  padding: 10px;
  background-color: red;
  flex-grow: 1;
}

#child {
  height: 10000px;
  background-color: green;
}

body {
  overflow: hidden;
  color: #fff;
  font-weight: bold;
}

button {
  position: fixed;
  bottom: 20px;
  width: 140px;
  left: 20%;
  right: 0;
}
<div id="parent">
  PARENT
  <div id="something">Something</div>
  <div id="scroller">
    CHILD
    <div id="child">
      GRAND CHILD
      <button onclick="moveToTop()">Top</button>
    </div>
  </div>
</div>

整个问题是 scrollIntoView() 正在移动 window。但是由于 #parent 溢出被隐藏了,所以当 window 被移动时,这个元素本身就会中断。我可以建议为 #parent 设置一个 position: fixed,这将解决您的问题,但它通常会损害 布局

使用scroll()方法。滚动机制本身是:

scroller.scroll(0, child.offsetTop - 55);

child.offsetTop - 顶部元素;

55 - 从#parent的顶部到#scroller.

的顶部的距离

过渡动画必须在选择器 #scroller 中设置为 css。像那样:

#scroller {
  ...
  scroll-behavior: smooth;
}

function moveToTop() {
  console.log('MOVE TO TOP::');
  const child = document.getElementById('child');
  const scroller = document.getElementById('scroller');
  scroller.scroll(0, child.offsetTop - 55);
}
#parent {
  background-color: blue;
  padding: 10px;
  height: 500px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

#scroller {
  overflow: auto;
  padding: 10px;
  background-color: red;
  flex-grow: 1;
  scroll-behavior: smooth;
}

#child {
  height: 10000px;
  background-color: green;
}

body {
  overflow: hidden;
  color: #fff;
  font-weight: bold;
}

button {
  position: fixed;
  bottom: 20px;
  width: 140px;
  left: 20%;
  right: 0;
}
<div id="parent">
  PARENT
  <div id="something">Something</div>
  <div id="scroller">
    CHILD
    <div id="child">
      GRAND CHILD
      <button onclick="moveToTop()">Top</button>
    </div>
  </div>
</div>