css 防止滚动带有“overflow:隐藏”?

yvfmudvl  于 2023-02-14  发布在  其他
关注(0)|答案(2)|浏览(172)

overflow: hidden阻止用户使用输入设备滚动,但仍然可以使用focus()scrollIntoView()等滚动元素。我有一些应该使用overflow: hidden隐藏的内容,但在隐藏输入上调用focus()有时会导致浏览器滚动overflow: hidden元素并显示隐藏的内容。
下面是一个演示,其中正确的元素应该始终隐藏:

document.querySelector('input').focus();
// document.querySelector('.right').scrollIntoView(); works too
body {
  overflow: hidden;
  margin: 0;
}

.container {
  width: 200vw;
  display: flex;
}

.left {
  width: 100vw;
  border: 1px solid red;
}

.right {
  width: 100vw;
  border: 1px solid blue;
}
<div class="container">
  <div class="left">left</div>
  <div class="right">
    right
    <input />
  </div>
</div>

position: fixed添加到.right可以解决这个问题,但是它引入了其他样式问题。如果不使用position: fixed,是否可以使body永远不可滚动?
我所面临的问题是由于React在隐藏输入具有autoFocus属性时调用focus()而引起的。它是在ReactDOMHostConfig的commitMount中调用的。即使我添加了一个lint规则来禁用React的autoFocus,也很可能有人会调用focus()并导致bug。

6yt4nkrj

6yt4nkrj1#

设置溢出:在html和body元素上隐藏,这样body就不能滚动了。然后,你设置overflow:在.right元素上滚动,这样如果在隐藏输入上调用focus(),则滚动的是.right元素而不是body。

html,
body {
  height: 100%;
  overflow: hidden;
}

.container {
  width: 200vw;
  height: 100%;
  display: flex;
}

.left {
  width: 100vw;
  height: 100%;
  border: 1px solid red;
}

.right {
  width: 100vw;
  height: 100%;
  border: 1px solid blue;
  overflow: scroll;
}
wlzqhblo

wlzqhblo2#

    • 使用JavaScript**
document.querySelector('input').focus();
document.querySelector('.right').scrollIntoView();

document.querySelector('.left').addEventListener('click', function(event) {
  document.querySelector('input').focus();
  document.querySelector('.right').scrollIntoView();
    console.log('focus input');
});

// Reset the scroll from javascript
window.onscroll = function() {
  window.scrollTo(0, 0);
  console.log('reset scroll');
};
body {
  overflow: hidden;
  margin: 0;
}

.container {
  width: 200vw;
  display: flex;
}

.left {
  width: 100vw;
  border: 1px solid red;
}

.right {
  width: 100vw;
  border: 1px solid blue;
}
<div class="container">
  <div class="left">left - click me</div>
  <div class="right">
    right
    <input />
  </div>
</div>

相关问题