【问题标题】:Transitioning an element from fixed to static positioning makes page jump to the top将元素从固定定位转换为静态定位使页面跳转到顶部
【发布时间】:2020-04-04 11:59:31
【问题描述】:

查看following example。我们有一个绿色块。纵向时,应固定在屏幕顶部。在横向时,它应该是静态的。有一些媒体查询可以控制这种行为。

将页面向下滚动到一定距离(无论它有多长),然后在 devtools 中将方向更改为横向,您会注意到屏幕跳到页面顶部。是什么导致这种情况发生?

如果您尝试手动更改 CSS 类以使块静态(我的意思是不改变方向),它不会跳到顶部。所以页面上有一个手动删除的按钮,试试看吧。

我还发现,如果你将这个绿色块的宽度更改为例如 10% 或给它“底部:0”,它不会导致屏幕跳跃。

它在 Chrome 中重现(macOS 和 Android,而不是在 iOS 上重现)

来自以上链接的示例代码:

document.addEventListener('DOMContentLoaded', () => {
    const page = document.querySelector('.page');
    const action = document.querySelector('.action');

    action.onclick = () => {
        page.classList.toggle('page_pinned');
    };
});
* {
  margin: 0;
  padding: 0;
}

html, body {
  width: 100%;
}

body {
  min-height: 5000px;
  background-image: linear-gradient(to top, black, white);
}

.sticky {
  width: 100%;
  height: 200px;
}

.sticky {
  background: green;
  margin-top: 1px;
}

.action {
  position: fixed;
  bottom: 0;
  left: 0;
  padding: 10px;
  font-size: 1.5em;
  background: white;
  border: 1px solid black;
}

@media (orientation: portrait) {
  .page_pinned .sticky {
    position: fixed;
  }
}

@media (orientation: landscape) {
  .page_pinned .sticky {
    position: absolute;
  }
}
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
        <link href="style.css" rel="stylesheet" />
        <script src="script.js"></script>
    </head>
    <body>
        <div class="page page_pinned">
            <div class="sticky"></div>
        </div>
        <button class="action">Click me to toggle fixed/static positioning</button>
    </body>
</html>

【问题讨论】:

  • 这个问题很有吸引力。对于解决方案,我们可以使用 JavaScript 方向检测,然后为横向添加一个新类并更改位置。但是为什么滚动跳到顶部以及为什么它没有发生在我编辑的代码 sn-p 中?你可以测试一下。

标签: javascript html css google-chrome


【解决方案1】:

起初,我觉得我很奇怪,我简化了您的问题并对其进行了测试,并且所有结果都与您的结果相同。直到看到这句话:

它在 Chrome 中重现(macOS 和 Android,而不是在 iOS 上重现)

我在 macOS Catalina 上的 FirefoxSafari 上测试了您的 given link,您的代码没有问题并且运行良好。

  • Firefox,macOS 上的响应式设计模式 (Galaxy S9):

    此屏幕截图是在将方向从纵向更改为横向后捕获的,并且不影响滚动

  • Safari,响应式设计模式(iPhone 8 Plus):

    正如您所见,改变方向也不会影响滚动。

  • Google Chrome,在 macOS 上切换设备工具栏 (Galaxy S5):

    正如您所说,在将方向从 portrait 更改为 landscape 后,在 Google Chrome 上,滚动条跳到了顶部。绝对是谷歌浏览器的一个BUG,因为从landscpaeportrait都不会发生这种情况,当子节点将更改其 位置 时,它只会从 portraitlandscape 发生。对于其他情况,它可以正常工作。

解决方案

对于这种情况,我决定更改解决方案,新的解决方案应该涵盖 Google Chrome 上的错误,并且在其他浏览器上正常工作,我省略了您的媒体查询,使用 static 而不是 absolute用于消除粘滞情况并为方向情况添加两个 CSS 类和用于处理交互的微小 JavaScript 代码:

var addClass = function () {
    var ori = screen.orientation.type;
    var bodyClassList = document.body.classList;

    if (ori === 'portrait-primary') {
        bodyClassList.add('portrait');
        bodyClassList.remove('landscape');
    } else {
        bodyClassList.remove('portrait');
        bodyClassList.add('landscape');
    }
};

addClass();
screen.orientation.onchange = addClass;
* {
    margin: 0;
    padding: 0;
}

html, body {
    width: 100%;
}

body {
    min-height: 5000px;
    background-image: linear-gradient(to top, black, white);
}

.sticky {
    width: 100%;
    height: 200px;
    background: green;
    margin-top: 1px;
}

body.portrait .sticky {
    position: fixed;
}

body.landscape .sticky {
    position: static;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ori</title>
</head>
<body>
    <div class="sticky"></div>
</body>
</html>

提示:我们应该报告这个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 2015-02-27
    • 2017-09-22
    • 2023-04-06
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多