javascript - 修正 header 广告背景过度滚动

原文 标签 javascript jquery css twitter-bootstrap sass

问题

我在页面顶部有一个简单的全角标头,上面有一个非固定的背景图片(即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

最佳答案

您正在尝试固定标头,而过度滚动的主体会产生橡皮筋的效果。我必须在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上使用上述丑陋的骇客。您可以进行一些性能改进:


throttle the callback,但这可能会导致动作缓慢;
在另一个CSS类和use that class name on the body instead of changing the body style directly中的margin-top中硬编码标头的高度,但这会给您带来更少的灵活性。

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

相关文章:

javascript - Javascript-我可以拦截对document.location.href的调用吗?

javascript - 如何在angularjs中保存 View

javascript - javascript函数在更新面板中进行完整的回发

jquery - 如何替换 AngularJS 指令链接函数中的元素?

javascript - jQuery使用父属性附加元素

html - 如何使用FF中的/Bootstrap防止标签溢出到多行

css - 带有图标的响应式,粘性,CSS形状,可能吗?

javascript - 如何结合html,css和javascript编码来使轮播工作?

html - Display:block是否正在创建额外的填充?

javascript - 网站流量跟踪整合