【问题标题】:Fix masthead background on overscroll修复过度滚动时的标头背景
【发布时间】:2019-01-11 23:50:15
【问题描述】:

问题

我的页面顶部有一个简单的全角标头,带有非固定背景图片(即background-attachment: scroll)和一些标题文本。一切看起来都很好,但是当用户向上“过度滚动”时,“溢出”是白色的。为了解决这个问题,我想在用户这样做时固定背景的位置,以便内容向下移动但背景保持不变。

示例代码

index.html

<div class="masthead">
  </div class="container">
    <h1>Hello, World</h1>
    <p>Lorem ipsum dolor</p>
  </div>
</div>

main.scss

/*...*/
.masthead {
  display: block;
  text-align: center;
  color: white;
  background-image: url('http://via.placeholder.com/1900x1250/ff6666/000000');
  background-repeat: no-repeat;
  background-attachment: scroll;
  background-position: center center;
  background-size: cover;
}
/*...*/

为什么overscroll-behavior-y: none 不行

首先,Safari/WebKit 尚不支持此功能,但我也认为这有点激进。我非常喜欢过度滚动的感觉,我想保留这种感觉,同时保持 UI 看起来干净。

怪癖

当我自己尝试执行此操作时,我发现添加 background-attachment: fixed 属性会稍微移动图像的位置。此外,即使背景是固定的,标头也不会延伸到溢出中,因此它的背景仍然是白色的。

我正在使用

  • SCSS
  • jQuery
  • bootstrap

【问题讨论】:

  • 感谢您提出的精心设计的问题。您介意添加一点代码,以便我们查看您的文档和 SCSS 的结构吗?
  • @Queder 谢谢,刚刚更新。

标签: javascript jquery css twitter-bootstrap sass


【解决方案1】:

您正在尝试修复标头,而过度滚动的主体会产生橡皮筋效果。我不得不在 iPhone 5C 上对此进行测试,因为如果您没有运行 OSX,桌面浏览器不会过度滚动,因此请记住,这些结果仅限于旧版本的 iOS(10.something)。以下是我的发现:

糟糕的解决方案:更改窗口滚动的 CSS

您可以为窗口滚动事件添加一个事件监听器,并在用户滚动到顶部时固定标头的位置(,当window.scrollY 属性为负数时):

CSS

body {
    margin: 0;
    padding: 0;
}

.masthead {
    overflow: auto;
    /* move this div to a gpu-processed layer */
    -webkit-transform: translate3d(0, 0, 0); /* for iOS <8.1 */
    transform: translate3d(0, 0, 0);
}

.fixed-top {
    position: fixed;
    top: 0;
    width: 100%;
}

JavaScript

var masthead = document.querySelector(".masthead");
var mastheadHeight = masthead.clientHeight;
var topContentMargin = 16;
mastheadHeight += topContentMargin;

window.addEventListener("scroll", function(e) {
    fixMastheadOnOverscroll();
});

function fixMastheadOnOverscroll() {
    let overscrollingTop = window.scrollY < 0;
    if (overscrollingTop) {
        masthead.classList.add("fixed-top");
        document.body.style.marginTop = mastheadHeight + "px";
    } else {
        masthead.classList.remove("fixed-top");
        document.body.style.marginTop = "0px";
    }
}

代码分解

您可以猜到,此代码只是在用户过度滚动时将标头固定到顶部。一些挑剔的 分:

  • 标头上的overflow: auto 修复了不过度滚动时折叠的页边距;
  • 添加transform 是一种已知的技巧,可以将元素提升到它自己的层并使用GPU 渲染它。过度滚动时,它是否使标头的定位更快?我不知道,这只是一个待处理的建议。
  • 过度滚动时向正文添加边距会使内容呈现在标头下方;如果你不这样做,它只会在固定的标头下方呈现。
  • 由于内容的上边距在过度滚动时会塌陷,因此我们将其高度添加到正文的边距中,这样当正文弹回原位时用户不会看到内容上下跳跃。

为什么不好?

据我所知,在滚动时触发 DOM 更改功能的成本很高。 From Twitter's own dev team:

将处理程序附加到窗口滚动事件是一个非常非常糟糕的主意。

事件监听器几乎连续触发函数。 iOS due to Apple engineers making the callback fire only at the end of the scroll event 上也可能有一些奇怪的行为(我认为)。

很好的解决方案

¯\(ツ)

老实说,如果不使用overscroll-behaviour-y,我不知道该怎么做。您只能通过检测浏览器在 iOS 上使用上面的丑陋黑客。您可以进行一些性能改进:

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多