【问题标题】:jQuery Sticky Sidebar failingjQuery Sticky Sidebar 失败
【发布时间】:2010-08-03 12:53:04
【问题描述】:

首先这段代码不是我写的。我是在别人的网站上找到的,我想通过自己尝试来学习。但是我不能让它工作。我已经用谷歌搜索了代码,以防它是一个免费提供的 jQuery 插件或任何东西,但我在网络上的任何地方都找不到它。

我有我的侧边栏(带有 id #sidebar),并给了它“粘性”类,我在页面顶部包含了 jQuery,我已经把这段代码放在了头部:

<!-- Floating sidebar jQuery --> 
        <script type="text/javascript"> 
            var Sticky = function( $obj, opts ){

               $(window).scroll( 
                  function(e){
                     Sticky.onScroll(e, $obj, opts );
                  });

            }
            Sticky.onScroll = function( e, $o, opts ){

               var iScrollTop = $(window).scrollTop();
               var sClass = "sticky";

               //set original data
               if( !$o.data(sClass) ){
                  $o.data(sClass, {css:{position:$o.css('position'),top:$o.css('top')}, offset:$o.offset()} );
               }
               var oOrig = $o.data(sClass);
               var bIsSticky = $o.hasClass(sClass);

               if( iScrollTop > oOrig.offset.top && !bIsSticky ){
                  $o.css({position:'fixed',top:0}).addClass(sClass);
               }else if(iScrollTop < oOrig.offset.top && bIsSticky){
                  $o.css(oOrig.css).removeClass(sClass);
               }   

            }

            Sticky( $('#sidebar') );

        </script> 

如您所见,最后的 JS 行 Sticky( $('#sidebar') ); 在 #sidebar 元素上触发。但是,当您向下滚动时,此错误会写入 Chrome 的日志:

未捕获的类型错误:无法读取未定义的属性“偏移量”

Firebug 有点啰嗦,说:

oOrig 未定义:if( iScrollTop > oOrig.offset.top && !bIsSticky ){

我正在尽力理解这一点,但有人可以帮我看看为什么它不起作用吗?

谢谢!

杰克

【问题讨论】:

  • 如果你把console.log($o.data(sClass));放在var oOrig = $o.data(sClass);之前,输出是什么?我在代码中看不到错误。添加一些log 调用并检查变量的内容。还要检查if( !$o.data(sClass) )语句中的代码是否被执行。

标签: javascript jquery sticky


【解决方案1】:

哇,新答案...谢谢菲利克斯

将函数调用包装在一个就绪函数中。

$(function() {
    Sticky($('#sidebar'));
});

当您调用 Sticky($('#sidebar')) 时,dom 很可能还没有准备好,所以当 .data 用于在 $o 上设置数据时,它实际上什么都不做:

$o.data(sClass, {css:{position:$o.css('position'),top:$o.css('top')}, offset:$o.offset()} );].  

所以当它在线获取数据时:

var oOrig = $o.data(sClass);

它实际上无法获取数据。

这是因为 dom 元素还没有准备好被操作,因为 dom 还没有准备好。

旧答案(不正确!)

$.offset 是一个函数。

行中的问题:

if( iScrollTop > oOrig.offset.top && !bIsSticky ){

就是:oOrig.offset 是一个函数,而不是一个变量。所以oOrig.offset.top 无效。只需调用该函数,它就会返回一个带有您可以访问的 top 属性的变量:

if( iScrollTop > oOrig.offset().top && !bIsSticky ){

说明:

oOrig.offset 是对函数的引用(jquery 中的offset 函数)。

您必须调用该函数才能访问.top 属性。

【讨论】:

  • 恐怕仍然会触发相同的错误,控制台只是给出相同的消息,但偏移后有几个括号! :( 编辑:Chrome 现在说“未捕获的类型错误:无法调用未定义的方法 'offset'”
  • 它仍然说 oOrig 是未定义的。
  • 这个答案是错误的。为什么这些赞成票? offset 不是 oOrig 上的函数。如果仔细观察,oOrig 是存储在$o.data(sClass) 中的对象,即{css:{position:$o.css('position'),top:$o.css('top')}, offset:$o.offset()}。即使它是一个函数,它也会抛出另一个错误并且不是 oOrig 是未定义的
  • @Bob:在您所说的if 语句中,oOrig.offset 实际上 一个变量。 oOrig 来自 .data(),所以它应该是一个普通的旧对象,具有 3 个属性,csstopoffset。查看//set original data 注释正下方的行。在我看来,问题在于$o.data(sClass, {/*...*/}) 没有正确发生。
  • @Bob Fincheimer:可能发生 ;) 我希望您不会被我之前评论的前两句话冒犯。我只是想知道为什么人们在没有验证的情况下如此迅速地对听起来合理的答案进行投票。
【解决方案2】:

您使用的代码似乎过于复杂。我写了一篇关于如何实现这一点的教程,该教程应该更容易实现且不易出错。

http://andrewhenderson.me/tutorial/jquery-sticky-sidebar/

【讨论】:

    猜你喜欢
    • 2012-05-11
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 2013-08-10
    • 2018-02-09
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多