1/** 2 * @name jQuery Stick 'em 3 * @author Trevor Davis 4 * @version 1.4.1 5 * 6 * $('.container').stickem({ 7 * item: '.stickem', 8 * container: '.stickem-container', 9 * stickClass: 'stickit', 10 * endStickClass: 'stickit-end', 11 * offset: 0, 12 * onStick: null, 13 * onUnstick: null 14 * }); 15 */ 16 17;(function($, window, document, undefined) { 18 19 var Stickem = function(elem, options) { 20 this.elem = elem; 21 this.$elem = $(elem); 22 this.options = options; 23 this.metadata = this.$elem.data("stickem-options"); 24 this.$win = $(window); 25 }; 26 27 Stickem.prototype = { 28 defaults: { 29 item: '.stickem', 30 container: '.stickem-container', 31 stickClass: 'stickit', 32 endStickClass: 'stickit-end', 33 offset: 0, 34 start: 0, 35 onStick: null, 36 onUnstick: null 37 }, 38 39 init: function() { 40 var _self = this; 41 42 //Merge options 43 _self.config = $.extend({}, _self.defaults, _self.options, _self.metadata); 44 45 _self.setWindowHeight(); 46 _self.getItems(); 47 _self.bindEvents(); 48 49 return _self; 50 }, 51 52 bindEvents: function() { 53 var _self = this; 54 55 _self.$win.on('scroll.stickem', $.proxy(_self.handleScroll, _self)); 56 _self.$win.on('resize.stickem', $.proxy(_self.handleResize, _self)); 57 }, 58 59 destroy: function() { 60 var _self = this; 61 62 _self.$win.off('scroll.stickem'); 63 _self.$win.off('resize.stickem'); 64 }, 65 66 getItem: function(index, element) { 67 var _self = this; 68 var $this = $(element); 69 var item = { 70 $elem: $this, 71 elemHeight: $this.height(), 72 $container: $this.parents(_self.config.container), 73 isStuck: false 74 }; 75 76 //If the element is smaller than the window 77 if(_self.windowHeight > item.elemHeight) { 78 item.containerHeight = item.$container.outerHeight(); 79 item.containerInner = { 80 border: { 81 bottom: parseInt(item.$container.css('border-bottom'), 10) || 0, 82 top: parseInt(item.$container.css('border-top'), 10) || 0 83 }, 84 padding: { 85 bottom: parseInt(item.$container.css('padding-bottom'), 10) || 0, 86 top: parseInt(item.$container.css('padding-top'), 10) || 0 87 } 88 }; 89 90 item.containerInnerHeight = item.$container.height(); 91 item.containerStart = item.$container.offset().top - _self.config.offset + _self.config.start + item.containerInner.padding.top + item.containerInner.border.top; 92 item.scrollFinish = item.containerStart - _self.config.start + (item.containerInnerHeight - item.elemHeight); 93 94 //If the element is smaller than the container 95 if(item.containerInnerHeight > item.elemHeight) { 96 _self.items.push(item); 97 } 98 } else { 99 item.$elem.removeClass(_self.config.stickClass + ' ' + _self.config.endStickClass); 100 } 101 }, 102 103 getItems: function() { 104 var _self = this; 105 106 _self.items = []; 107 108 _self.$elem.find(_self.config.item).each($.proxy(_self.getItem, _self)); 109 }, 110 111 handleResize: function() { 112 var _self = this; 113 114 _self.getItems(); 115 _self.setWindowHeight(); 116 }, 117 118 handleScroll: function() { 119 var _self = this; 120 121 if(_self.items.length > 0) { 122 var pos = _self.$win.scrollTop(); 123 124 for(var i = 0, len = _self.items.length; i < len; i++) { 125 var item = _self.items[i]; 126 127 //If it's stuck, and we need to unstick it, or if the page loads below it 128 if((item.isStuck && (pos < item.containerStart || pos > item.scrollFinish)) || pos > item.scrollFinish) { 129 item.$elem.removeClass(_self.config.stickClass); 130 131 //only at the bottom 132 if(pos > item.scrollFinish) { 133 item.$elem.addClass(_self.config.endStickClass); 134 } 135 136 item.isStuck = false; 137 138 //if supplied fire the onUnstick callback 139 if(_self.config.onUnstick) { 140 _self.config.onUnstick(item); 141 } 142 143 //If we need to stick it 144 } else if(item.isStuck === false && pos > item.containerStart && pos < item.scrollFinish) { 145 item.$elem.removeClass(_self.config.endStickClass).addClass(_self.config.stickClass); 146 item.isStuck = true; 147 148 //if supplied fire the onStick callback 149 if(_self.config.onStick) { 150 _self.config.onStick(item); 151 } 152 } 153 } 154 } 155 }, 156 157 setWindowHeight: function() { 158 var _self = this; 159 160 _self.windowHeight = _self.$win.height() - _self.config.offset; 161 } 162 }; 163 164 Stickem.defaults = Stickem.prototype.defaults; 165 166 $.fn.stickem = function(options) { 167 //Create a destroy method so that you can kill it and call it again. 168 this.destroy = function() { 169 this.each(function() { 170 new Stickem(this, options).destroy(); 171 }); 172 }; 173 174 return this.each(function() { 175 new Stickem(this, options).init(); 176 }); 177 }; 178 179})(jQuery, window , document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.