I just completed a plugin that will also do this. I had problems trying to change the position of an element from fixed to absolute and vice versa when it hit the top or bottom of the viewport. This did not work for me at different screen resolutions, since I needed to set the left property. Basically, just reference the plugin and call it on the element you want to scroll through:
$ myDiv.fixposition ({boundingElement: myBoundary}) // myBoundary is the element in which you want your scrollable div to stay inside.
(function($) { $.extend($.fn, { fixposition: function(opts) { return this.each(function() { var defaults = { boundingElement: "", bottomOffset: 20 }; var options = defaults; if (typeof(options) != 'object') options = { }; options = $.extend(options, opts); $this = $(this); var $boundEl = $("#" + options.boundingElement); var bottomBound = $boundEl.offset().top + $boundEl.height(); var maxTop = bottomBound - $this.height() - options.bottomOffset; var minTop = $this.offset().top; var newTopPos = null; var parentTopOffset = $this.parent().offset().top; if($("body").length > 0 && options.boundingElement != "") { $(window).scroll(function () { var scrollY = $(window).scrollTop(); if($this.length > 0) { if ($this.offset().top != (scrollY - parentTopOffset)) { newTopPos = scrollY - parentTopOffset; } if (newTopPos != null) { if (newTopPos > maxTop - parentTopOffset) { newTopPos = maxTop - parentTopOffset - options.bottomOffset; } else if (newTopPos < minTop - parentTopOffset) { newTopPos = minTop - parentTopOffset; } $this .stop() .css({"top": newTopPos}); } } }); } }); } }); })(jQuery);
(function($) { $.extend($.fn, { fixposition: function(opts) { return this.each(function() { var defaults = { boundingElement: "", bottomOffset: 20 }; var options = defaults; if (typeof(options) != 'object') options = { }; options = $.extend(options, opts); $this = $(this); var $boundEl = $("#" + options.boundingElement); var bottomBound = $boundEl.offset().top + $boundEl.height(); var maxTop = bottomBound - $this.height() - options.bottomOffset; var minTop = $this.offset().top; var newTopPos = null; var parentTopOffset = $this.parent().offset().top; if($("body").length > 0 && options.boundingElement != "") { $(window).scroll(function () { var scrollY = $(window).scrollTop(); if($this.length > 0) { if ($this.offset().top != (scrollY - parentTopOffset)) { newTopPos = scrollY - parentTopOffset; } if (newTopPos != null) { if (newTopPos > maxTop - parentTopOffset) { newTopPos = maxTop - parentTopOffset - options.bottomOffset; } else if (newTopPos < minTop - parentTopOffset) { newTopPos = minTop - parentTopOffset; } $this .stop() .css({"top": newTopPos}); } } }); } }); } }); })(jQuery);
source share