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
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
Share Improve this question asked Aug 3, 2010 at 12:53 JackJack 9,79418 gold badges77 silver badges115 bronze badges 1-
What is the output if you put
console.log($o.data(sClass));
beforevar oOrig = $o.data(sClass);
? I cannot see an error in the code. Add somelog
calls and check the contents of the variables. Also check, whether the code insideif( !$o.data(sClass) )
statement is executed. – Felix Kling Commented Aug 3, 2010 at 13:07
2 Answers
Reset to default 5Wow, 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.
The code you're using seems overly plicated. 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/