From c09448c6db54a349e88997f7ac9c06fc52855118 Mon Sep 17 00:00:00 2001 From: Rafal Lindemann Date: Tue, 19 Feb 2013 23:01:55 +0100 Subject: [PATCH 1/5] Nice handling of stickies bigger than the current window --- README.md | 11 +++++++++ index.html | 6 +++++ jquery.stickem.js | 59 +++++++++++++++++++++++++++++++++++++---------- screen.css | 7 +++++- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2535baa..5229078 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,9 @@ Container that you want the sticky item to be contained in. **stickClass: 'stickit'**
Class added to the sticky item once it should start being sticky. +**activeStickClass: 'stickit-active'**
+Class added to the sticky item handled by the plugin (ie. not bigger than container) + **endStickClass: 'stickit-end'**
Class added to the sticky item once it has reached the end of the container @@ -52,6 +55,14 @@ Do you already have a fixed horizontal header on the page? Offset stick 'em by t **start: 0**
If your sticky item isn't at the top of the container, tell it where it should start being sticky. +**overflow: true**
+If a sticky is bigger than window, you'll be able to scroll it by scrolling the window. You can +disable this for backwards compatibility. + +**topProperty: 'top'**
+CSS property to use for positioning the item. You can use 'top', 'margin-top' or false to control it +by css classes yourself. This is *required* for overflowing items. + **onStick: null**
You can create a callback function that fires when an item gets "stuck". The item gets passed back. diff --git a/index.html b/index.html index 82bbaf6..faba550 100644 --- a/index.html +++ b/index.html @@ -13,11 +13,17 @@

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Heading

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

diff --git a/jquery.stickem.js b/jquery.stickem.js index df80958..8b6bb7b 100644 --- a/jquery.stickem.js +++ b/jquery.stickem.js @@ -22,6 +22,7 @@ this.options = options; this.metadata = this.$elem.data("stickem-options"); this.$win = $(window); + this.lastPos = 0; }; Stickem.prototype = { @@ -30,10 +31,13 @@ container: '.stickem-container', stickClass: 'stickit', endStickClass: 'stickit-end', + activeStickClass: 'stickit-active', offset: 0, start: 0, onStick: null, - onUnstick: null + onUnstick: null, + overflow: true, + topProperty: 'top', }, init: function() { @@ -74,7 +78,8 @@ }; //If the element is smaller than the window - if(_self.windowHeight > item.elemHeight) { + if(_self.config.overflow || _self.windowHeight > item.elemHeight) { + item.overflowAmount = Math.max(0, item.elemHeight - _self.windowHeight); item.containerHeight = item.$container.outerHeight(); item.containerInner = { border: { @@ -94,10 +99,11 @@ //If the element is smaller than the container if(item.containerInnerHeight > item.elemHeight) { _self.items.push(item); + item.$elem.addClass(_self.config.activeStickClass); + return; } - } else { - item.$elem.removeClass(_self.config.stickClass + ' ' + _self.config.endStickClass); } + item.$elem.removeClass(_self.config.stickClass + ' ' + _self.config.endStickClass + ' ' + _self.config.activeStickClass); }, getItems: function() { @@ -125,9 +131,19 @@ var item = _self.items[i]; //If it's stuck, and we need to unstick it - if(item.isStuck && (pos < item.containerStart || pos > item.scrollFinish)) { + if(item.isStuck && (pos < item.containerStart || pos > item.scrollFinish + item.overflowAmount + || (item.isOverflowing > 0 && pos < _self.lastPos) + || (item.isOverflowing < 0 && pos > _self.lastPos) + )) { + item.isOverflowing = 0; item.$elem.removeClass(_self.config.stickClass); - + // set current position as absolute + if (_self.config.topProperty) { + item.$elem.css(_self.config.topProperty, + Math.max(item.containerStart, Math.min(pos - item.overflowAmount, item.scrollFinish)) + - item.$elem.offsetParent().offset().top + 'px' + ); + } //only at the bottom if(pos > item.scrollFinish) { item.$elem.addClass(_self.config.endStickClass); @@ -142,16 +158,35 @@ //If we need to stick it } else if(item.isStuck === false && pos > item.containerStart && pos < item.scrollFinish) { - item.$elem.removeClass(_self.config.endStickClass).addClass(_self.config.stickClass); - item.isStuck = true; - - //if supplied fire the onStick callback - if(_self.config.onStick) { - _self.config.onStick(item); + if (_self.config.topProperty) { + if (item.overflowAmount) { + var itemOffsetTop = item.$elem.offset().top; + if (_self.lastPos < pos && itemOffsetTop + item.elemHeight < pos + _self.windowHeight) { + item.$elem.css(_self.config.topProperty, (-item.overflowAmount) + 'px'); + item.isOverflowing = 1; + } else if (_self.lastPos > pos && itemOffsetTop > pos) { + item.$elem.css(_self.config.topProperty, '0px'); + item.isOverflowing = -1; + } else if (itemOffsetTop > pos + _self.windowHeight || itemOffsetTop + item.elemHeight < pos) { + item.$elem.css(_self.config.topProperty, '0px'); + } else { + return; + } + } else { + item.$elem.css(_self.config.topProperty, '0px'); } + } + item.$elem.removeClass(_self.config.endStickClass).addClass(_self.config.stickClass); + item.isStuck = true; + + //if supplied fire the onStick callback + if(_self.config.onStick) { + _self.config.onStick(item); + } } } } + _self.lastPos = pos; }, setWindowHeight: function() { diff --git a/screen.css b/screen.css index 147df2f..60a3aa4 100644 --- a/screen.css +++ b/screen.css @@ -48,14 +48,19 @@ p { margin-bottom: 1.5em; } +.stickit-active { + position: absolute; + right: 0px; +} + .stickit { margin-left: 660px; position: fixed; top: 0; + right: auto; } .stickit-end { - bottom: 40px; position: absolute; right: 0; } \ No newline at end of file From 828e24f79bcb222a549cd39d7b404a506c4d341c Mon Sep 17 00:00:00 2001 From: Rafal Lindemann Date: Wed, 20 Feb 2013 00:15:32 +0100 Subject: [PATCH 2/5] fix overflow on resize --- jquery.stickem.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/jquery.stickem.js b/jquery.stickem.js index 8b6bb7b..15f9278 100644 --- a/jquery.stickem.js +++ b/jquery.stickem.js @@ -74,12 +74,13 @@ $elem: $this, elemHeight: $this.height(), $container: $this.parents(_self.config.container), - isStuck: false + isStuck: $this.hasClass(_self.config.stickClass) }; //If the element is smaller than the window if(_self.config.overflow || _self.windowHeight > item.elemHeight) { item.overflowAmount = Math.max(0, item.elemHeight - _self.windowHeight); + if (item.overflowAmount && item.isStuck) item.isOverflowing = 1; item.containerHeight = item.$container.outerHeight(); item.containerInner = { border: { @@ -132,15 +133,15 @@ //If it's stuck, and we need to unstick it if(item.isStuck && (pos < item.containerStart || pos > item.scrollFinish + item.overflowAmount - || (item.isOverflowing > 0 && pos < _self.lastPos) - || (item.isOverflowing < 0 && pos > _self.lastPos) + || (item.isOverflowing > 0 && pos > _self.lastPos) + || (item.isOverflowing < 0 && pos < _self.lastPos) )) { item.isOverflowing = 0; item.$elem.removeClass(_self.config.stickClass); // set current position as absolute if (_self.config.topProperty) { item.$elem.css(_self.config.topProperty, - Math.max(item.containerStart, Math.min(pos - item.overflowAmount, item.scrollFinish)) + Math.max(item.containerStart, Math.min(pos + parseInt(item.$elem.css('top'),10), item.scrollFinish)) - item.$elem.offsetParent().offset().top + 'px' ); } @@ -163,12 +164,15 @@ var itemOffsetTop = item.$elem.offset().top; if (_self.lastPos < pos && itemOffsetTop + item.elemHeight < pos + _self.windowHeight) { item.$elem.css(_self.config.topProperty, (-item.overflowAmount) + 'px'); - item.isOverflowing = 1; + item.isOverflowing = -1; } else if (_self.lastPos > pos && itemOffsetTop > pos) { item.$elem.css(_self.config.topProperty, '0px'); - item.isOverflowing = -1; + item.isOverflowing = 1; } else if (itemOffsetTop > pos + _self.windowHeight || itemOffsetTop + item.elemHeight < pos) { item.$elem.css(_self.config.topProperty, '0px'); + // } else if (item.$elem.hasClass(_self.config.stickClass)) { + // // we actually are not sticked... + // item.isOverflowing = -1; } else { return; } From a609e3480c078e331a44027046093bc0199434bc Mon Sep 17 00:00:00 2001 From: Rafal Lindemann Date: Wed, 20 Feb 2013 00:39:31 +0100 Subject: [PATCH 3/5] allow invalidation though scroll event --- jquery.stickem.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jquery.stickem.js b/jquery.stickem.js index 15f9278..becc2c0 100644 --- a/jquery.stickem.js +++ b/jquery.stickem.js @@ -133,8 +133,8 @@ //If it's stuck, and we need to unstick it if(item.isStuck && (pos < item.containerStart || pos > item.scrollFinish + item.overflowAmount - || (item.isOverflowing > 0 && pos > _self.lastPos) - || (item.isOverflowing < 0 && pos < _self.lastPos) + || (item.isOverflowing > 0 && pos >= _self.lastPos) + || (item.isOverflowing < 0 && pos <= _self.lastPos) )) { item.isOverflowing = 0; item.$elem.removeClass(_self.config.stickClass); From 636db6d1c8d1774f3483117ac36a400e1b3c4518 Mon Sep 17 00:00:00 2001 From: Rafal Lindemann Date: Wed, 20 Feb 2013 22:41:00 +0100 Subject: [PATCH 4/5] overflowStickClass --- jquery.stickem.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/jquery.stickem.js b/jquery.stickem.js index becc2c0..433f120 100644 --- a/jquery.stickem.js +++ b/jquery.stickem.js @@ -31,6 +31,7 @@ container: '.stickem-container', stickClass: 'stickit', endStickClass: 'stickit-end', + overflowStickClass: 'stickit-overflow', activeStickClass: 'stickit-active', offset: 0, start: 0, @@ -104,7 +105,8 @@ return; } } - item.$elem.removeClass(_self.config.stickClass + ' ' + _self.config.endStickClass + ' ' + _self.config.activeStickClass); + item.$elem.removeClass(_self.config.stickClass + ' ' + _self.config.endStickClass + + ' ' + _self.config.activeStickClass + ' ' + _self.config.overflowStickClass); }, getItems: function() { @@ -148,6 +150,8 @@ //only at the bottom if(pos > item.scrollFinish) { item.$elem.addClass(_self.config.endStickClass); + } else if (pos > item.containerStart) { + item.$elem.addClass(_self.config.overflowStickClass); } item.isStuck = false; @@ -180,7 +184,8 @@ item.$elem.css(_self.config.topProperty, '0px'); } } - item.$elem.removeClass(_self.config.endStickClass).addClass(_self.config.stickClass); + item.$elem.removeClass(_self.config.endStickClass + ' ' + _self.config.overflowStickClass) + .addClass(_self.config.stickClass); item.isStuck = true; //if supplied fire the onStick callback From a1e4a22817c0a157b0641cb0f518bd08d65cbd8e Mon Sep 17 00:00:00 2001 From: Rafal Lindemann Date: Wed, 20 Feb 2013 23:54:18 +0100 Subject: [PATCH 5/5] some cleanup --- jquery.stickem.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/jquery.stickem.js b/jquery.stickem.js index 433f120..ab732df 100644 --- a/jquery.stickem.js +++ b/jquery.stickem.js @@ -170,18 +170,15 @@ item.$elem.css(_self.config.topProperty, (-item.overflowAmount) + 'px'); item.isOverflowing = -1; } else if (_self.lastPos > pos && itemOffsetTop > pos) { - item.$elem.css(_self.config.topProperty, '0px'); + item.$elem.css(_self.config.topProperty, ''); item.isOverflowing = 1; } else if (itemOffsetTop > pos + _self.windowHeight || itemOffsetTop + item.elemHeight < pos) { - item.$elem.css(_self.config.topProperty, '0px'); - // } else if (item.$elem.hasClass(_self.config.stickClass)) { - // // we actually are not sticked... - // item.isOverflowing = -1; + item.$elem.css(_self.config.topProperty, ''); } else { return; } } else { - item.$elem.css(_self.config.topProperty, '0px'); + item.$elem.css(_self.config.topProperty, ''); } } item.$elem.removeClass(_self.config.endStickClass + ' ' + _self.config.overflowStickClass) @@ -194,8 +191,8 @@ } } } + _self.lastPos = pos; } - _self.lastPos = pos; }, setWindowHeight: function() {