8

我有一个项目,其要求是#footer向上移动页脚 (),同时以类似视差的效果向下滚动页面。当您开始向下滚动页面时,页脚应该开始向上移动,直到它在视口(底部)中可见。

当页脚到达视口顶部时,页脚应该已经覆盖了前<div>半部分的大部分内容。

该页面可能具有类似的 html 结构,如下所示:

<body>
    <div id="sectionA" class="div">First section</div>
    <div id="sectionB" class="div">Second section</div>
    <div id="sectionC" class="div">Third section
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
    </div>
    <div id="footer" class="div cf">Footer</div>
</body>

类似视差的效果是通过 javascript/jQuery 向(相对定位的)页脚的 CSS 属性添加动态负值来实现的。top这是重要的代码:

var $window = jQuery(window),
    $footer = jQuery("#footer"),
    $viewport = window.innerHeight,
    $startEffect = $footer.offset().top - $viewport;

function footerParallax() {
    var $scrollPos = $window.scrollTop() - $startEffect,
        $ratio = 0.6;
    $footer.css({
        top: -($scrollPos * $ratio)
    });
}

$window.scroll(function () {
    footerParallax();
});

(显而易见的)问题是,一旦top属性开始获得负值,页脚就会开始远离页面底部。

我准备了一个JSFIDDLE并为每个部分分配了颜色并body使其更清晰。滚动到底部后,body(深红色)在页脚下方可见。

我尝试了什么?

  • 修改margin-top而不是top属性:  这样做可以解决问题,但是<div>必须由页脚覆盖的前面(#sectionC在上面的示例中)与页脚的内容重叠并破坏其布局,无论它由于其z-index属性而不可见(在小提琴中添加了一些浮动框以使其明显...... clearfix hack 也无济于事。)
  • static为页脚设置位置:既不影响top也不margin-top影响static元素。
  • 动态更改/减少heightof#sectionC而不是top页脚以产生向上移动第二个的效果:  页脚一旦height等于就停止移动0(不允许负大小或负填充)
  • height动态更改html和/或body标签无济于事。

我还尝试了一些视差插件,例如skrollrskrollr-stylesheets以及其他一些插件。

此解决方案的问题(与其他解决方案相同)是它在以 px 测量的页脚的特定(偏移)位置中继并在data属性中设置,但如果内容动态变化,例如使用 masonry 插件在文档的另一部分,度量变得不准确,页脚可能开始移动得太早或太晚。

顺便说一句,其他 CSS 粘页脚技术不起作用,因为它们实际上将页脚推到页面底部,而我们正在做相反的事情。

我想问题是:

  • 向上移动时如何使页脚保持在页面底部?- 或者 -
  • 如何减少0文档末尾和页脚底部边缘之间的间隙?

我开始认为这个问题没有真正的解决方案,或者我已经太累了,看不到明显的东西。我有兴趣通过 CSS / javascript / jQuery 或以上所有方法学习替代解决方案或 hack。

请记住,我不是在问如何创建视差效果,除非完全不同的方法(或对现有 js 代码的调整)解决了位置问题。

重要提示:请考虑这是一个带有 的 WP 站点XHTML 1.0 Transitional DOCTYPE,并且已经安装了许多其他 jQuery 插件,如 masonry、scrollTo、jQuery UI 等。我可能无法控制从原始结构更改很多东西(我不想to) 所以我们的想法是在不破坏太多东西的情况下从模块化脚本中实现这一点。

编辑#1:添加了一个图形来澄清问题。

  • A。显示一个向下滚动到末尾的常规网页。红色方块代表视口,为了便于说明,页脚(灰色)略微向右移动。body也有一个带红色的背景颜色(在正常情况下不可见),仅用于说明目的。注意height每个部分的 以及height页脚的 由它们的内容(表单、图像、文本等)决定,因此不是固定的。

  • B。显示当前问题:如果页脚在向下滚动页面时以类似视差的效果向上滑动(请参阅JSFIDDLEheight以供参考),它会开始覆盖它上面的任何前面的部分(不修改它自己的部分或height前面部分的部分)并且它也开始与页面底部分离,因此body的颜色背景变得可见。注意:视口越大(例如全屏模式),页脚向上移动得越高(并且覆盖的内容越多)

  • C。是预期的结果:页脚应该粘在页面底部,换句话说,它应该是页面完全向下滚动后的最后一个可见元素(而不是图 B 中的正文背景)。注意每个部分(包括页脚)的内容和大小应该(理想情况下)保持不变。话虽如此,向页脚添加填充底部或增加其高度并不是预期的结果,因为它会破坏其原始视觉布局。

在此处输入图像描述

4

3 回答 3

6

更新后的版本

下面是一个更新版本,应该更符合您的要求。

这个版本回到relative页脚元素的定位并使用margin-top它来定位它。

margin-top根据先前元素的偏移量、高度和当前窗口滚动位置计算得出。然后它使用

  1. 如果页脚在屏幕外开始时的视口高度
  2. $startEffect如果页脚在屏幕上开始,页脚元素 ( ) 的初始顶部值

确定margin-top的实际值。

为了帮助防止页脚的布局受此影响,将页脚的内容包装在绝对定位的 div 中对提供的示例代码起到了作用。

示例小提琴

CSS:

#footer > div {
    position: absolute;
    top: 0;
    left: 0;
    ...
}

HTML:

<div id="footer" class="div cf"><div>Footer</div></div>

代码:

var $window = jQuery(window),
    $footer = jQuery("#footer"),
    $viewport = window.innerHeight,
    $startEffect = $footer.offset().top;
    $prev = $footer.prev(),
    $useStartEffect = $startEffect < $viewport;


function footerParallax() {
    var $scrollPos = $window.scrollTop() - $startEffect,
        $ratio = 0.6;

    var prevOffset = $prev.offset().top + $prev.height() - $window.scrollTop();
    var marginTop = 0;

    if(prevOffset < $viewport && prevOffset < $startEffect) {
        if($useStartEffect) {
            marginTop = (prevOffset - $startEffect)*$ratio;
        } else {
            marginTop = (prevOffset - $viewport)*$ratio;       
        }
    }

    $footer.css({
        "margin-top": marginTop + 'px'
    });
}

$window.scroll(function () {
    footerParallax();
});

footerParallax();
于 2013-08-31T17:09:59.587 回答
3

它是如何解决的?

正如我在问题中提到的,我太累了,看不到明显的东西,但@dc5 的回答让我走上了正确的轨道:

To help keep the footer's layout from being affected, 
wrapping the content of the footer in an absolutely 
positioned div does the trick

根据该评论,答案变得比他建议的整个代码更简单:

  • div(动态)使用jQuery的.wrapInner()方法将页脚的内容包装在绝对定位中
  • margin-top通过设置属性而不是属性来为top页脚设置动画

所以这个额外的 CSS :

#footerInnerWrapper {
    position: absolute;
    top:0;
    left:0;
    width: 100%;
    background-color: #666 /* same as footer */
}

和调整后的原始代码

var $window = jQuery(window),
    $footer = jQuery("#footer"),
    $viewport = window.innerHeight,
    $startEffect = $footer.offset().top - $viewport;

// add inner wrapper
$footer.wrapInner('<div id="footerInnerWrapper" />');

function footerParallax() {
    var $scrollPos = $window.scrollTop() - $startEffect,
        $ratio = 0.6;
    $footer.css({
        // top: -($scrollPos * $ratio) 
        marginTop: -($scrollPos * $ratio)
    });
}

$window.scroll(function () {
    footerParallax();
});

成功了。见JSFIDDLE

于 2013-09-01T07:58:58.327 回答
1

这就是我认为您需要的,当页脚完全滚动到视图中时,页脚会粘住:

jsFiddle

添加的代码:

function footerParallax() {
    var $scrollPos = $window.scrollTop() - $startEffect,
        $ratio = 0.6,
        $newTop = -($scrollPos * $ratio),
        $oldTop = parseInt($footer.css('top')),
        $nonRelTop = $footer.offset().top - $oldTop,
        $wanted = ($window.scrollTop()+$viewport-$footer.height());
    if ($nonRelTop + $newTop < $wanted) {
        $('#sectionC').css('display', 'none');
        $wanted = ($window.scrollTop()+$viewport-$footer.height());
        $nonRelTop = $footer.offset().top - $oldTop;
        $newTop = $wanted - $nonRelTop;
    } else {
        $('#sectionC').css('display', 'block');
    }    
    $footer.css('top', $newTop);
}

$window.scroll(footerParallax);

在CSS中我添加了这个,这样$footer.css('top')就不会产生NaN

#footer {
    top:0;
    /* ... */
}

编辑:在进一步澄清 OP 之后的全新方法。我现在有一个固定位置的页脚,当用户滚动通过文档的一半时,它开始增加高度以占据整个屏幕。HTML、CSS 和 Javascript 都已更新以实现此目的:

jsFiddle

于 2013-08-31T17:13:48.613 回答