Skip to content

Instantly share code, notes, and snippets.

@bob-moore
Created September 8, 2016 17:10
Show Gist options
  • Save bob-moore/605d7585f4b156bdfc49efd82b884ac9 to your computer and use it in GitHub Desktop.
Save bob-moore/605d7585f4b156bdfc49efd82b884ac9 to your computer and use it in GitHub Desktop.
Sticky Sidebar
( function ( $ ) {
var $window = $( window );
var settings;
var defaults = {
'topoffset' : 0,
'bottomoffset' : 0,
'wrapper' : null
};
$.fn.StickIt = function( options ) {
// Extend default settings
settings = $.extend( {}, defaults, options );
// Create objects
return this.each( function() {
return new StickyWidget( $( this ) );
});
};
function StickyWidget( $el ) {
var $parent = $el.parents().first();
var $wrapper = $el.data( 'wrapper' ) || settings.wrapper;
var triggers = {};
var offsets = {};
var waypoints = {};
var $container;
// Init object on window load
$window.on( 'load', init );
function init() {
// Create Wrapper
if( $wrapper === 'undefined' || $wrapper === null ) {
var parents = $el.parents();
$wrapper = parents[1];
}
$wrapper = $( $wrapper );
// Create Container
$el.wrap( '<div id="fixed-container"></div>' );
$container = $( '#fixed-container' );
// Set up offsets
offsets = {
top : parseInt( $el.data( 'topoffset' ) ) || parseInt( settings.topoffset ),
bottom : parseInt( $el.data( 'bottomoffset' ) ) || parseInt( settings.bottomoffset ),
total : parseInt( $parent.offset().top ),
original : parseInt( $el.position().top )
};
bind_events();
calculate_positions( create_triggers );
}
function bind_events() {
$window.on( 'load', init );
$window.on( 'resize', refresh );
}
function create_triggers() {
// Create Triggers to fire directly on element, for scrolling down
waypoints.affix = $container.waypoint( function( direction ) {
// If we are scrolling down, affix element
if( direction === 'down' ) {
affix_element();
return this;
}
// If we are scrolling up, defix element
if( direction === 'up' ) {
defix_element();
return this;
}
return this;
}, { offset : offsets.top } );
// Create Triggers to fire on parent, when we reach the bottom
waypoints.defix = $wrapper.waypoint( function( direction ) {
// If we are scrolling up, affix element
if( direction === 'up' ) {
affix_element();
return this;
}
// If we've reach the bottom, defix element
if( direction === 'down' ) {
affix_bottom();
return this;
}
}, { offset : triggers.bottom });
}
function calculate_positions( callback ) {
triggers.top = offsets.top || 0;
triggers.bottom = 0 - ( $wrapper.outerHeight() - $el.height() ) + offsets.top + offsets.bottom;
return callback();
}
function refresh() {
return calculate_positions( function() {
waypoints.affix[0].destroy();
waypoints.defix[0].destroy();
if( $parent.outerWidth() >= $wrapper.innerWidth() ) {
defix_element();
} else {
dimension_element();
create_triggers();
}
return;
});
}
var calculate_bottom = function() {
return $wrapper.height() - $el.outerHeight() - offsets.bottom ;
};
function affix_element() {
var position = window.pageYOffset - offsets.total;
if( position < 0 ) {
return;
}
position_element( position ).addClass( 'affixed' );
}
function defix_element( placement ) {
$el.attr( 'style', '' );
}
function affix_bottom() {
$el.css( { 'position' : 'absolute', 'top' : calculate_bottom(), 'width' : 'auto' } );
}
function position_element() {
$el.css( { 'position' : 'fixed', 'top' : offsets.top, 'width' : $parent.width() } );
return $el;
}
function dimension_element() {
$el.css( { 'width' : $parent.width() } );
$container.css( { 'height' : $el.height() } );
return $el;
}
return {
parent : $parent
}
}
}( jQuery ));
// Activating the plugin
jQuery( function( $ ) {
$( '#sticky-widget-area' ).StickIt( {
topoffset : 30,
bottomoffset : 30,
wrapper : '#primary'
});
}); // end document ready
<div id="primary">
<div id="main" class="column md-8">
<!-- Main Content Here -->
</div>
<div id="sidebar" class="column md-4">
<div id="not-sticky-widget-area">
<!-- Put not sticky sidebar here -->
</div>
<div id="sticky-widget-area">
<!-- Put sticky sidebar here -->
</div>
</div>
</div>
<!-- ============ Sample from sidebar.php for WordPress ============ -->
<aside id="sidebar" class="column sm-4">
<?php if ( is_active_sidebar( 'not-sticky-sidebar' ) ) : ?>
<div class="widget-area secondary sidebar" role="complementary">
<?php dynamic_sidebar( 'not-sticky-sidebar' ); ?>
</div>
<?php endif; ?>
<?php if ( is_active_sidebar( 'sticky-sidebar' ) ) : ?>
<div id="sticky-widget-area" class="widget-area secondary sidebar" role="complementary">
<?php dynamic_sidebar( 'sticky-sidebar' ); ?>
</div>
<?php endif; ?>
</aside>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment