Skip to content

Instantly share code, notes, and snippets.

@Ticolyle
Created August 30, 2016 21:23
Show Gist options
  • Select an option

  • Save Ticolyle/8df41bab0639d9c918a27f2b8cab4402 to your computer and use it in GitHub Desktop.

Select an option

Save Ticolyle/8df41bab0639d9c918a27f2b8cab4402 to your computer and use it in GitHub Desktop.
Wee sticky module
{
"name": "wee-sticky",
"version": "0.2.0",
"description": "Make elements sticky based on a certain scroll point.",
"homepage": "https://caddis.co",
"author": "Ryan Payne - Caddis",
"autoload": true,
"extension": true,
"data": {},
"style": {
"build": []
},
"script": {
"build": []
},
"dependencies": {
"wee": "^3.0.0"
}
}
Wee.fn.make('sticky', {
/**
* Init sticky element
*
* @param {string} selector
* @param {object} options
* @param {string} [options.stickyClass=-is-sticky]
* @param {string} [options.namespace=sticky]
* @param {number} [options.offset=0]
* @param {number} [options.start=0]
* @param {string} [options.container]
* @param {string} [options.bottomClass=-is-bottom]
* @param {(Array|function|string)} [options.stuck] - callback when element is sticky
* @param {(Array|function|string)} [options.unstuck] - callback when element is no longer sticky
*/
init: function(selector, options) {
var settings = $.extend({
stickyClass: '-is-sticky',
namespace: 'sticky',
offset: 0,
start: 0,
bottomClass: '-is-bottom',
interval: 250
}, options),
priv = this.$private;
priv.$element = $(selector);
priv.settings = settings;
priv.initObservable();
priv.initScroll();
priv.initInterval();
},
/**
* Destroy sticky element
*
* @param {object} options
* @param {string} [options.namespace=sticky]
*/
destroy: function(options) {
var settings = $.extend({
namespace: 'sticky'
}, options);
$.events.off(false, '.' + settings.namespace);
this.$set('sticky', false);
this.$unobserve('sticky');
clearInterval(this.$private.interval);
this.$drop('sticky');
}
}, {
/**
* Init observable method
*
* @private
*/
initObservable: function() {
this.$set('sticky', false);
this.$observe('sticky', function(data) {
data ? this.stick() : this.unstick();
}, {
scope: this
});
},
/**
* Init scroll events
*
* @private
*/
initScroll: function() {
var scope = this;
scope.scrolled = false;
$(Wee._win).on('scroll.' + scope.settings.namespace, function() {
scope.scrolled = true;
});
},
/**
* Init interval
*
* @private
*/
initInterval: function() {
var $win = $(Wee._win),
scope = this,
settings = scope.settings,
container = settings.container,
$container = $(container),
bottomClass = settings.bottomClass;
scope.interval = setInterval(function() {
if (scope.scrolled) {
var pos = $win.scrollTop(),
sticky = scope.$get('sticky'),
start = settings.start;
scope.scrolled = false;
if (! sticky && pos > start) {
scope.$set('sticky', true);
} else if (sticky && pos <= start) {
scope.$set('sticky', false);
}
if (container) {
if (sticky && pos > ($container.offset().top - settings.offset) + ($container.height() - scope.$element.height())) {
scope.$element.addClass(bottomClass);
} else {
scope.$element.removeClass(bottomClass);
}
}
}
}, settings.interval);
},
/**
* Make element sticky
*
* @private
*/
stick: function() {
var settings = this.settings,
stuckCallback = settings.stuck;
this.$element.addClass(settings.stickyClass);
if (stuckCallback) {
stuckCallback();
}
},
/**
* Make element not sticky
*
* @private
*/
unstick: function() {
var settings = this.settings,
unstuckCallback = settings.unstuck;
this.$element.removeClass(settings.stickyClass);
if (unstuckCallback) {
unstuckCallback();
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment