草庐IT

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

coder 2023-08-07 原文

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

当页脚到达视口(viewport)的顶部时,它应该已经覆盖了大部分前面的 <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 向(相对定位)页脚的 top CSS 属性添加动态负值来实现的。这是重要的代码:
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 属性(在 fiddle 中添加了一些 float 框以使其明显......一个 clearfix hack 也没有帮助。)
  • 为页脚设置 static 位置:topmargin-top 都不会影响 static 元素。
  • 动态更改/减少 height#sectionC 而不是页脚的 top 以产生向上移动第二个的效果:一旦 height 等于 0,页脚停止移动(不允许负大小或负填充)119507
  • 动态更改 height 和/或 html 标签的 body 无济于事。

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

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

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

    我想问题是:
  • 如何在页脚向上移动时保持在页面底部? - 或 -
  • 如何减少文档末尾和页脚底边之间到0 的间隙?

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

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

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

    编辑 #1 :添加了一个图形来澄清问题。
  • 图A 。显示一个向下滚动到最后的常规网页。红色方块代表视口(viewport),页脚(灰色)略微向右移动以进行说明。 body 也有一个红色的背景颜色(在正常情况下不可见)也只是为了说明目的。 NOTE :每个部分的 height 以及页脚的 height 由它们的内容(形式、图像、文本等)决定,因此不是固定的。
  • 图 B 。显示当前问题:如果页脚以类似视差的效果向上滑动(请参阅 JSFIDDLE 以供引用),同时向下滚动页面,它将开始覆盖其上方的任何前面部分(无需修改其自己的 height 或前面的 height部分)并且它也开始将自己与页面底部分开,因此 body 的颜色背景变得可见。 NOTE :视口(viewport)越大(例如全屏模式)页脚向上移动得越高(它覆盖的内容越多)
  • 图 C 。是预期的结果:页脚应该粘在页面底部,换句话说,它应该是页面完全向下滚动后的最后一个可见元素(而不是图B中的正文背景。) 每个部分(包括页脚)的内容和大小应该(理想情况下)保持不变。话虽如此,向页脚添加填充底部或增加其高度并不是预期的结果,因为它会破坏其原始视觉布局。

  • 最佳答案

    更新版本

    以下是更符合您要求的更新版本。

    此版本回溯到 relative页脚元素的定位和使用 margin-top来定位它。
    margin-top是根据前一个元素的偏移量、高度和当前窗口滚动位置计算出来的。然后它使用

  • 如果页脚从屏幕外开始,则视口(viewport)高度
  • 如果页脚在屏幕上开始,则页脚元素的初始顶部值 ( $startEffect )

  • 确定 margin-top 的实际值。

    为了帮助防止页脚的布局受此影响,将页脚的内容包装在绝对定位的 div 中可以解决所提供的示例代码。

    Example Fiddle

    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();
    

    关于javascript - 如何将页脚粘贴到页面底部,同时以类似视差的效果向上移动页脚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18502430/

    有关javascript - 如何将页脚粘贴到页面底部,同时以类似视差的效果向上移动页脚?的更多相关文章

    1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

      我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

    2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

      关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

    4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

      给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

    5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

      我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

    6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

      我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

    7. ruby - 如何指定 Rack 处理程序 - 2

      Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

    8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

      在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

    9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

      我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

    10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

      我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

    随机推荐