简体   繁体   English

将元素从固定转换到 static 定位使页面跳转到顶部

[英]Transitioning an element from fixed to static positioning makes page jump to the top

Look at the following example .下面的例子 We have a green block.我们有一个绿色块。 When in portrait orientation, it should be fixed at the top of the screen.纵向时,应固定在屏幕顶部。 When in landscape orientation, it should be static.在横向时,它应该是 static。 There are media queries that control this behavior.有控制这种行为的媒体查询。

Scroll the page down to some distance (no matter how long it is), then in devtools change the orientation to landscape and you'll notice that the screen jumps to the top of the page.将页面向下滚动一段距离(不管它有多长),然后在 devtools 中将方向更改为横向,您会注意到屏幕跳转到页面顶部。 What causes this to happen?是什么导致这种情况发生?

If you try to manually change CSS classes to make the block static (I mean not on orientation change), it won't jump to the top.如果您尝试手动更改 CSS 类以制作块 static (我的意思是不改变方向),它不会跳到顶部。 So there is a button on the page for manual removing, try it out.所以页面上有一个手动删除的按钮,试试看。

I also found that if you change the width of this green block to, for instance, 10% or give it "bottom: 0" it won't cause the screen to jump.我还发现,如果你将这个绿色块的宽度更改为例如 10% 或给它“底部:0”,它不会导致屏幕跳跃。

It reproduces in Chrome (macOS and Android, not reproducing on iOS)它在 Chrome 中重现(macOS 和 Android,不在 iOS 上重现)

Sample code from the link above:来自上面链接的示例代码:

 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>

At first, I was weird for me, I simplify your question and test it on and on put all results were the same as your result.起初,我对我来说很奇怪,我简化了您的问题并对其进行了测试,并且所有结果都与您的结果相同。 Until I saw this sentence:直到我看到这句话:

It reproduces in Chrome (macOS and Android, not reproducing on iOS)它在 Chrome 中重现(macOS 和 Android,不在 iOS 上重现)

I tested your given link on the Firefox and Safari on macOS Catalina and your codes have no issue and work well.我在 macOS Catalina 上的FirefoxSafari上测试了您给定的链接,您的代码没有问题并且运行良好。

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

    This screenshot captured after changing orientation from portrait to landscape and it didn't affect on the scroll此屏幕截图是在将方向从纵向更改为横向后捕获的,并且不影响滚动

    在此处输入图像描述

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

    As you see changing orientation didn't affect scroll too.如您所见,改变方向也不会影响滚动。

    在此处输入图像描述

  • Google Chrome, Toggle Device Toolbar (Galaxy S5) on macOS: macOS 上的 Google Chrome、切换设备工具栏 (Galaxy S5):

    Just like you said, on Google Chrome after changing orientation from portrait to landscape the scroll jumped to the top.就像您说的那样,在将方向从纵向更改为横向后,在 Google Chrome 上,滚动条跳到了顶部。 definitely, it is a BUG of Google Chrome, because it doesn't' happen from landscpae to portrait , and it just happens from portrait to landscape when a child node will be changed its position .当然,这是谷歌浏览器的一个BUG ,因为它不会从landscpaeportrait发生,它只是在子节点更改为position时从纵向横向发生。 for other cases, it works without issue.对于其他情况,它可以正常工作。

    在此处输入图像描述

Solution解决方案

For such these cases I decide to change the solution and the new solution should cover the bug on Google Chrome and works properly the same as before on other browsers, I omit your media queries, use static instead of absolute for removing sticky situation and add two CSS classes for the orientation situations and a tiny JavaScript code for handling the interaction:对于这些情况,我决定更改解决方案,新的解决方案应该涵盖 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>

Hint : we should report this bug.提示:我们应该报告这个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM