javascript - 修复过度滚动时的 header 背景

标签 javascript jquery css twitter-bootstrap sass

问题

我的页面顶部有一个简单的全 Angular header ,带有非固定背景图像(即 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 属性会稍微移动图像的位置。此外,即使背景是固定的, header 也不会延伸到溢出部分,因此它的背景仍然是白色。

我正在使用

  • SCSS
  • jQuery
  • Bootstrap

最佳答案

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

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

您可以向窗口滚动事件添加一个事件监听器,并在用户滚动到顶部时固定 header 的位置(,当 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";
    }
}

代码分解

您可以猜到,这段代码只是在用户过度滚动时将刊头固定在顶部。一些挑剔的 要点:

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

为什么不好?

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

It’s a very, very, bad idea to attach handlers to the window scroll event.

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

好的解决方案

¯\(ツ)

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

关于javascript - 修复过度滚动时的 header 背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51683570/

相关文章:

javascript - 表单中自定义字段的指令 [范围未更新]

html - 如何制作 .svg 文件以填充其 <div> 容器的 100% 宽度?

javascript - 通过 javascript 或 jquery 将 anchor 的状态更改为事件状态

javascript - 什么时候应该使用错误优先回调?

javascript - React NPM 包(Dragula)在开发中有效,但在生产中无效

jquery - 从 Angular 广播到 jQuery 监听器

jquery - Knockout.js 和 null

css - 导航栏问题

JavaScript 问题 : regex issue finding matches

javascript - 使用 jquery ajax 加载外部 javascript 文件的最佳方法?