jQuery 粘性侧边栏失败

发布于 2024-09-12 10:55:34 字数 1728 浏览 2 评论 0 原文

首先我没有编写这段代码。我在别人的网站上找到了它,我想通过自己尝试来学习它。但是我无法让它发挥作用。我在谷歌上搜索了代码,以防它是一个免费的 jQuery 插件或其他任何东西,但我在网络上的任何地方都找不到它。

我有我的侧边栏(带有 id #sidebar),并给了它“sticky”类,我在页面顶部包含了 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){

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

谢谢!

杰克

First of all I did not write this code. I found it on somebody else's website and I want to learn from it by trying it out myself. However I can't make it work. I've googled for the code in case it's a jQuery plugin that's freely available or anything, but I can't find it anywhere on the web.

I have my sidebar (with id #sidebar) and have given it the class "sticky", I've included jQuery at the top of the page, and I've put this code in place in the head:

<!-- 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> 

As you can see, the final JS line Sticky( $('#sidebar') ); fires on the #sidebar element. However, when you scroll down, this error is written to Chrome's log:

Uncaught TypeError: Cannot read property 'offset' of undefined

Firebug is a bit more verbose, and says:

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

I'm trying my best to understand this but can somebody help me see why it's not working?

Thanks!

Jack

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天荒地未老 2024-09-19 10:55:34

哇,新答案...谢谢 felix

将函数调用包装在一个准备好的函数中。

$(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 是对函数的引用(offset jquery 中的函数)。

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

Wow, new answer...Thanks felix

wrap the function call in a ready function.

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

The dom is most likely not ready when you call Sticky($('#sidebar')) so when .data is used to set data on $o it actual does nothing:

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

So when it gets the data on line:

var oOrig = $o.data(sClass);

it cannot actualy get the data.

This is because the dom elements are not ready to be manipulated because the dom is not ready yet.

OLD ANSWER (NOT RIGHT!)

$.offset is a function.

The problem in the line:

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

is that: oOrig.offset is a function, not a variable. So oOrig.offset.top is not valid. Simply call the function and it will return a variable with the top property which you can access:

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

Explination:

oOrig.offset is a reference to a function (the offset function in jquery).

You must call the function to access the .top property.

祁梦 2024-09-19 10:55:34

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

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

The code you're using seems overly complicated. I wrote a tutorial on how to achieve this that should be much easier to implement and less error prone.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文