Good evening all,

I have a sticky menu that I am using on a website but I cannot get it to stay within its parent div. Below is the javascript code. Any help/feedback would be greatly appreciated.

<!------------------------ Javascript ------------------------->

(function($){

var settings = {
speed: 400 //animation duration
, easing: "linear" //use easing plugin for more options
, padding: 0
, constrain: false
}
, $window = $(window)
, stickyboxes = []
, methods = {

init:function(opts){
settings = $.extend(settings,opts);
return this.each(function () {
var $this = $(this);
setPosition($this);
stickyboxes[stickyboxes.length] = $this;
moveIntoView();
});
}

, remove:function(){
return this.each(function () {
var sticky = this;
$.each(stickyboxes, function (i, $sb) {
if($sb.get(0) === sticky){
reset(null, $sb);
stickyboxes.splice(i, 1);
return false;
}
});
});
}

, destroy: function () {
$.each(stickyboxes, function (i, $sb) {
reset(null, $sb);
});
stickyboxes=[];
$window.unbind("scroll", moveIntoView);
$window.unbind("resize", reset);
return this;
}

};


var moveIntoView = function () {
$.each(stickyboxes, function (i, $sb) {
var $this = $sb
, data = $this.data("stickySB");
if (data) {
var sTop = $window.scrollTop() -data.offs.top
, currOffs = $this.offset()
, origTop = data.orig.offset.top - data.offs.top
, animTo = origTop;
//scrolled down out of view
if (origTop < sTop) {
//make sure to stop inside parent
if ((sTop + settings.padding) > data.offs.bottom)
animTo = data.offs.bottom;
else animTo = sTop + settings.padding;
}
$this
.stop()
.animate(
{top: animTo}
, settings.speed
, settings.easing
);
}
});
}

var setPosition = function ($sb) {
if ($sb) {
var $this = $sb
, $parent = $this.parent()
, parentOffs = $parent.offset()
, currOff = $this.offset()
, data = $this.data("stickySB");
if (!data) {
data = {
offs: {} // our parents offset
, orig: { // cache for original css
top: $this.css("top")
, left: $this.css("left")
, position: $this.css("position")
, marginTop: $this.css("marginTop")
, marginLeft: $this.css("marginLeft")
, offset: $this.offset()
}
}
}
//go up the tree until we find an elem to position from
while (parentOffs && "top" in parentOffs
&& $parent.css("position") == "static") {
$parent = $parent.parent();
parentOffs = $parent.offset();
}
if (parentOffs) { // found a postioned ancestor
var padBtm = parseInt($parent.css("paddingBottom"));
padBtm = isNaN(padBtm) ? 0 : padBtm;
data.offs = parentOffs;
data.offs.bottom = settings.constrain ?
Math.abs(($parent.innerHeight() - padBtm) - $this.outerHeight()) :
$(document).height();
}
else data.offs = { // went to far set to doc
top: 10
, left: 0
, bottom: $(document).height()
};
$this.css({
position: "absolute"
, top: Math.floor(currOff.top - data.offs.top) + "px"
, left: Math.floor(currOff.left - data.offs.left) + "px"
, margin: 0
, width: $this.width()
}).data("stickySB", data);
}
}

var reset = function (ev, $toReset) {
var stickies = stickyboxes;
if ($toReset) { // just resetting selected items
stickies = [$toReset];
}
$.each(stickies, function(i, $sb) {
var data = $sb.data("stickySB");
if (data) {
$sb.css({
position: data.orig.position
, marginTop: data.orig.marginTop
, marginLeft: data.orig.marginLeft
, left: data.orig.left
, top: data.orig.top
});
if (!$toReset) { // just resetting
setPosition($sb);
moveIntoView();
}
}
});
}

$window.bind("scroll", moveIntoView);
$window.bind("resize", reset);

$.fn.stickySidebar = function (method) {

if (methods[method]) {
return methods[method].apply(
this
, Array.prototype.slice.call(arguments, 1)
);
} else if (!method || typeof method == "object") {
return methods.init.apply(this, arguments);
}

}

})(jQuery);