123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- (function($){
- var settings = {
- speed: 350 //animation duration
- , easing: "linear" //use easing plugin for more options
- , padding: 10
- , 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: 0
- , 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);
|