如何将页脚粘贴到页面底部,同时向上移动以视差效果?

JFK*_*JFK 7 html javascript css jquery parallax

我有一个项目,其中要求#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>
Run Code Online (Sandbox Code Playgroud)

通过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();
});
Run Code Online (Sandbox Code Playgroud)

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

我准备了一个JSFIDDLE并为每个部分分配颜色并body使其更清晰.该body(暗红色)滚动至底部后躯下可见.

我试过了什么?

  • 修改margin-top而不是top属性:   这样做的技巧,但是<div>页脚必须覆盖的前面(#sectionC在上面的示例中)与页脚的内容重叠并打破其布局,无论它由于其z-index属性而不可见(在小提琴中添加了一些浮动框以使其显而易见......一个clearfix hack也无济于事.)
  • 一个设定static位置到页脚:既不topmargin-top有一个超过效应static元件.
  • 改变/动态地减少height#sectionC,而不是top页脚以产生移动第二向上的效果:   页脚停止如一旦移动height等于0(均未负大小或负补白被允许)
  • 更改height动态html和/或body标签无效.

我也尝试了一些视差插件,如skrollrskrollr-stylesheets以及其他一些.

此解决方案的问题(与其他解决方案相同)是它在px中测量并在data属性中设置的页脚的特定(偏移)位置中继,但是如果内容动态更改,例如使用砌体插件来排列元素该文件的另一部分,措施变得不准确,并且页脚可能开始过早或过晚.

顺便说一句,其他CSS粘页技术将无法正常工作,因为它们实际上将页脚推到了页面的底部,而在这里我们正在做相反的事情.

我想问题是:

  • 如何在页面向上移动时保持页脚粘到页面底部?- 要么 -
  • 如何减少0文档末尾和页脚底边之间的间隙?

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

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

重要提示:请考虑这是一个带有的WP站点XHTML 1.0 Transitional DOCTYPE,并安装了许多其他jQuery插件,如砌体,scrollTo,jQuery UI等.我可能无法控制从原始结构改变很多东西(我不想要因此,我们的想法是在不破坏太多东西和模块化脚本的情况下实现这一点.

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

  • 图A.显示滚动到最后的常规网页.红色方块表示视口,页脚(灰色)向右移动以进行说明.该body有一个红色的背景颜色(在正常情况下不可见)只是为了演示过.注意:height每个部分以及height页脚的内容由其内容(表单,图像,文本等)决定,因此不固定.

  • 图B.显示当前问题:如果页脚在向下滚动页面时向上滑动以类视差效果(请参阅JSFIDDLE以供参考),它会开始覆盖其上方的任何前一部分(无需修改其自身heightheight前面部分)并且它也开始从页面底部分离,因此body颜色背景变得可见.注意:视口越大(例如全屏模式)页脚向上移动越高(更多内容被覆盖)

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

在此输入图像描述

dc5*_*dc5 5

更新后的版本

以下是更新版本,可以更好地满足您的要求.

此版本返回到relative页脚元素的margin-top定位并用于定位它.

margin-top计算出以前的元素偏移量,高度和当前窗口滚动位置.然后它使用其中之一

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

确定margin-top的实际值.

为了帮助保持页脚的布局不受此影响,将页脚的内容包装在绝对定位的div中为所提供的示例代码提供了技巧.

示例小提琴

CSS:

#footer > div {
    position: absolute;
    top: 0;
    left: 0;
    ...
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<div id="footer" class="div cf"><div>Footer</div></div>
Run Code Online (Sandbox Code Playgroud)

码:

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();
Run Code Online (Sandbox Code Playgroud)


JFK*_*JFK 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
Run Code Online (Sandbox Code Playgroud)

基于该评论,答案变得比他提出的整个代码更简单,只需要:

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

所以这个额外的CSS:

#footerInnerWrapper {
    position: absolute;
    top:0;
    left:0;
    width: 100%;
    background-color: #666 /* same as footer */
}
Run Code Online (Sandbox Code Playgroud)

以及调整后的原始代码

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();
});
Run Code Online (Sandbox Code Playgroud)

成功了。参见JSFIDDLE