I have created a basic plugin using a Codepen that I found which allows for "sticky" elements to be displayed on site.
I've not written a plugin before and I seem to be getting confused with variables (var var_name, var $var_name etc.) and then also when referring back to them. I feel this misunderstanding is causing the problem with the plugin.
I have two elements that scroll with the page but stop when they reach the bottom of their parent. This works fine however the first element appears to be sticking to the bottom of the parent once it has reached the offset position of the following element. So to me it looks like the height of the 2nd element is being used to calculate the position of the first.
Below is the plugin and the two bits of code I'm using it initiate the plugin. I have set up a jsfiddle however it is coming up with an undefined is not a function error.
//Initiate plugin
$(window).load(function() {
$('.section-1-pin').sticky({
parent: '#section-1',
main: '.section-1-sibling'
});
$('.section-2-pin').sticky({
parent: '#section-2',
main: '.section-2-sibling'
});
});
//Plugin code in external file
(function($) {
$.fn.sticky = function( options ) {
return this.each(function() {
var $this = $(this);
options = options || {};
var parent = options.parent;
var $main = options.main;
if( !$this.parent().is('.wrap') ) {
$this.wrap( '<div class="wrap"></div>' );
}
$( '<div class="sticky-stop"></div>' ).insertAfter( parent );
measureheight = function() {
stickyHeight = $this.outerHeight();
mainHeight = $(String($main)).outerHeight();
var stickyStop = $(parent).next('.sticky-stop');
console.log(stickyHeight);
if ( (mainHeight - stickyHeight) > 0) {
$(parent).waypoint(function(direction) {
$(parent).toggleClass('sticky', direction === 'down');
});
$(stickyStop).waypoint(function(direction) {
$(parent).toggleClass('at-bottom', direction === 'down');
}, {
offset: function() {
return stickyHeight;
}
})
} else {
$(parent).waypoint('destroy');
}
};
$(window).resize(measureheight);
measureheight();
});
};
})(jQuery);
It's the stickyHeight variable that appears to be the problem. In the real world example section-1 has a height of 341px and section-2 has a height of 246px. The first section appear to stick too late and looking at the element offset prior to the element sticking it looks to be around 250px.
Any help would be greatly appreciated.
Thank you.
Edit Here is a link to http://jsfiddle.net/fn44qqjo/20/
The issue is present and representative of the problem however some of the CSS isn't sound so you will notice the sticky element change size etc. but that's fine.
The problem was that my variables in the measureheight
function were set as global. Putting var in front to make them local has fixed the issue. New code below;
(function($) {
$.fn.sticky = function( options ) {
return this.each(function() {
var $this = $(this);
options = options || {};
var parent = options.parent;
var $main = options.main;
if( !$this.parent().is('.wrap') ) {
$this.wrap( '<div class="wrap"></div>' );
}
$( '<div class="sticky-stop"></div>' ).insertAfter( parent );
measureheight = function() {
//Changed these to local variables
var stickyHeight = $this.outerHeight();
var mainHeight = $(String($main)).outerHeight();
var stickyStop = $(parent).next('.sticky-stop');
if ( (mainHeight - stickyHeight) > 0) {
$(parent).waypoint(function(direction) {
$(parent).toggleClass('sticky', direction === 'down');
});
$(stickyStop).waypoint(function(direction) {
$(parent).toggleClass('at-bottom', direction === 'down');
}, {
offset: function() {
return stickyHeight;
}
})
} else {
$(parent).waypoint('destroy');
}
};
$(window).resize( measureheight() );
measureheight()
});
};
})(jQuery);