411 lines
13 KiB
JavaScript
411 lines
13 KiB
JavaScript
"use strict";
|
|
|
|
var KTStickyHandlersInitialized = false;
|
|
|
|
// Class definition
|
|
var KTSticky = function(element, options) {
|
|
////////////////////////////
|
|
// ** Private Variables ** //
|
|
////////////////////////////
|
|
var the = this;
|
|
|
|
if ( typeof element === "undefined" || element === null ) {
|
|
return;
|
|
}
|
|
|
|
// Default Options
|
|
var defaultOptions = {
|
|
offset: 200,
|
|
reverse: false,
|
|
release: null,
|
|
animation: true,
|
|
animationSpeed: '0.3s',
|
|
animationClass: 'animation-slide-in-down'
|
|
};
|
|
////////////////////////////
|
|
// ** Private Methods ** //
|
|
////////////////////////////
|
|
|
|
var _construct = function() {
|
|
if ( KTUtil.data(element).has('sticky') === true ) {
|
|
the = KTUtil.data(element).get('sticky');
|
|
} else {
|
|
_init();
|
|
}
|
|
}
|
|
|
|
var _init = function() {
|
|
the.element = element;
|
|
the.options = KTUtil.deepExtend({}, defaultOptions, options);
|
|
the.uid = KTUtil.getUniqueId('sticky');
|
|
the.name = the.element.getAttribute('data-kt-sticky-name');
|
|
the.attributeName = 'data-kt-sticky-' + the.name;
|
|
the.attributeName2 = 'data-kt-' + the.name;
|
|
the.eventTriggerState = true;
|
|
the.lastScrollTop = 0;
|
|
the.scrollHandler;
|
|
|
|
// Set initialized
|
|
the.element.setAttribute('data-kt-sticky', 'true');
|
|
|
|
// Event Handlers
|
|
window.addEventListener('scroll', _scroll);
|
|
|
|
// Initial Launch
|
|
_scroll();
|
|
|
|
// Bind Instance
|
|
KTUtil.data(the.element).set('sticky', the);
|
|
}
|
|
|
|
var _scroll = function(e) {
|
|
var offset = _getOption('offset');
|
|
var release = _getOption('release');
|
|
var reverse = _getOption('reverse');
|
|
var st;
|
|
var attrName;
|
|
var diff;
|
|
|
|
// Exit if false
|
|
if ( offset === false ) {
|
|
_disable();
|
|
return;
|
|
}
|
|
|
|
offset = parseInt(offset);
|
|
release = release ? document.querySelector(release) : null;
|
|
|
|
st = KTUtil.getScrollTop();
|
|
diff = document.documentElement.scrollHeight - window.innerHeight - KTUtil.getScrollTop();
|
|
|
|
var proceed = (!release || (release.offsetTop - release.clientHeight) > st);
|
|
|
|
if ( reverse === true ) { // Release on reverse scroll mode
|
|
if ( st > offset && proceed ) {
|
|
if ( document.body.hasAttribute(the.attributeName) === false) {
|
|
|
|
if (_enable() === false) {
|
|
return;
|
|
}
|
|
|
|
document.body.setAttribute(the.attributeName, 'on');
|
|
document.body.setAttribute(the.attributeName2, 'on');
|
|
the.element.setAttribute("data-kt-sticky-enabled", "true");
|
|
}
|
|
|
|
if ( the.eventTriggerState === true ) {
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.on', the);
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.change', the);
|
|
|
|
the.eventTriggerState = false;
|
|
}
|
|
} else { // Back scroll mode
|
|
if ( document.body.hasAttribute(the.attributeName) === true) {
|
|
_disable();
|
|
document.body.removeAttribute(the.attributeName);
|
|
document.body.removeAttribute(the.attributeName2);
|
|
the.element.removeAttribute("data-kt-sticky-enabled");
|
|
}
|
|
|
|
if ( the.eventTriggerState === false ) {
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.off', the);
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.change', the);
|
|
the.eventTriggerState = true;
|
|
}
|
|
}
|
|
|
|
the.lastScrollTop = st;
|
|
} else { // Classic scroll mode
|
|
if ( st > offset && proceed ) {
|
|
if ( document.body.hasAttribute(the.attributeName) === false) {
|
|
|
|
if (_enable() === false) {
|
|
return;
|
|
}
|
|
|
|
document.body.setAttribute(the.attributeName, 'on');
|
|
document.body.setAttribute(the.attributeName2, 'on');
|
|
the.element.setAttribute("data-kt-sticky-enabled", "true");
|
|
}
|
|
|
|
if ( the.eventTriggerState === true ) {
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.on', the);
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.change', the);
|
|
the.eventTriggerState = false;
|
|
}
|
|
} else { // back scroll mode
|
|
if ( document.body.hasAttribute(the.attributeName) === true ) {
|
|
_disable();
|
|
document.body.removeAttribute(the.attributeName);
|
|
document.body.removeAttribute(the.attributeName2);
|
|
the.element.removeAttribute("data-kt-sticky-enabled");
|
|
}
|
|
|
|
if ( the.eventTriggerState === false ) {
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.off', the);
|
|
KTEventHandler.trigger(the.element, 'kt.sticky.change', the);
|
|
the.eventTriggerState = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (release) {
|
|
if ( release.offsetTop - release.clientHeight > st ) {
|
|
the.element.setAttribute('data-kt-sticky-released', 'true');
|
|
} else {
|
|
the.element.removeAttribute('data-kt-sticky-released');
|
|
}
|
|
}
|
|
}
|
|
|
|
var _enable = function(update) {
|
|
var top = _getOption('top');
|
|
top = top ? parseInt(top) : 0;
|
|
|
|
var left = _getOption('left');
|
|
var right = _getOption('right');
|
|
var width = _getOption('width');
|
|
var zindex = _getOption('zindex');
|
|
var dependencies = _getOption('dependencies');
|
|
var classes = _getOption('class');
|
|
|
|
var height = _calculateHeight();
|
|
var heightOffset = _getOption('height-offset');
|
|
heightOffset = heightOffset ? parseInt(heightOffset) : 0;
|
|
|
|
if (height + heightOffset + top > KTUtil.getViewPort().height) {
|
|
return false;
|
|
}
|
|
|
|
if ( update !== true && _getOption('animation') === true ) {
|
|
KTUtil.css(the.element, 'animationDuration', _getOption('animationSpeed'));
|
|
KTUtil.animateClass(the.element, 'animation ' + _getOption('animationClass'));
|
|
}
|
|
|
|
if ( classes !== null ) {
|
|
KTUtil.addClass(the.element, classes);
|
|
}
|
|
|
|
if ( zindex !== null ) {
|
|
KTUtil.css(the.element, 'z-index', zindex);
|
|
KTUtil.css(the.element, 'position', 'fixed');
|
|
}
|
|
|
|
if ( top >= 0 ) {
|
|
KTUtil.css(the.element, 'top', String(top) + 'px');
|
|
}
|
|
|
|
if ( width !== null ) {
|
|
if (width['target']) {
|
|
var targetElement = document.querySelector(width['target']);
|
|
if (targetElement) {
|
|
width = KTUtil.css(targetElement, 'width');
|
|
}
|
|
}
|
|
|
|
KTUtil.css(the.element, 'width', width);
|
|
}
|
|
|
|
if ( left !== null ) {
|
|
if ( String(left).toLowerCase() === 'auto' ) {
|
|
var offsetLeft = KTUtil.offset(the.element).left;
|
|
|
|
if ( offsetLeft >= 0 ) {
|
|
KTUtil.css(the.element, 'left', String(offsetLeft) + 'px');
|
|
}
|
|
} else {
|
|
KTUtil.css(the.element, 'left', left);
|
|
}
|
|
}
|
|
|
|
if ( right !== null ) {
|
|
KTUtil.css(the.element, 'right', right);
|
|
}
|
|
|
|
// Height dependencies
|
|
if ( dependencies !== null ) {
|
|
var dependencyElements = document.querySelectorAll(dependencies);
|
|
|
|
if ( dependencyElements && dependencyElements.length > 0 ) {
|
|
for ( var i = 0, len = dependencyElements.length; i < len; i++ ) {
|
|
KTUtil.css(dependencyElements[i], 'padding-top', String(height) + 'px');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var _disable = function() {
|
|
KTUtil.css(the.element, 'top', '');
|
|
KTUtil.css(the.element, 'width', '');
|
|
KTUtil.css(the.element, 'left', '');
|
|
KTUtil.css(the.element, 'right', '');
|
|
KTUtil.css(the.element, 'z-index', '');
|
|
KTUtil.css(the.element, 'position', '');
|
|
|
|
var dependencies = _getOption('dependencies');
|
|
var classes = _getOption('class');
|
|
|
|
if ( classes !== null ) {
|
|
KTUtil.removeClass(the.element, classes);
|
|
}
|
|
|
|
// Height dependencies
|
|
if ( dependencies !== null ) {
|
|
var dependencyElements = document.querySelectorAll(dependencies);
|
|
|
|
if ( dependencyElements && dependencyElements.length > 0 ) {
|
|
for ( var i = 0, len = dependencyElements.length; i < len; i++ ) {
|
|
KTUtil.css(dependencyElements[i], 'padding-top', '');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var _check = function() {
|
|
|
|
}
|
|
|
|
var _calculateHeight = function() {
|
|
var height = parseFloat(KTUtil.css(the.element, 'height'));
|
|
|
|
height = height + parseFloat(KTUtil.css(the.element, 'margin-top'));
|
|
height = height + parseFloat(KTUtil.css(the.element, 'margin-bottom'));
|
|
|
|
if (KTUtil.css(element, 'border-top')) {
|
|
height = height + parseFloat(KTUtil.css(the.element, 'border-top'));
|
|
}
|
|
|
|
if (KTUtil.css(element, 'border-bottom')) {
|
|
height = height + parseFloat(KTUtil.css(the.element, 'border-bottom'));
|
|
}
|
|
|
|
return height;
|
|
}
|
|
|
|
var _getOption = function(name) {
|
|
if ( the.element.hasAttribute('data-kt-sticky-' + name) === true ) {
|
|
var attr = the.element.getAttribute('data-kt-sticky-' + name);
|
|
var value = KTUtil.getResponsiveValue(attr);
|
|
|
|
if ( value !== null && String(value) === 'true' ) {
|
|
value = true;
|
|
} else if ( value !== null && String(value) === 'false' ) {
|
|
value = false;
|
|
}
|
|
|
|
return value;
|
|
} else {
|
|
var optionName = KTUtil.snakeToCamel(name);
|
|
|
|
if ( the.options[optionName] ) {
|
|
return KTUtil.getResponsiveValue(the.options[optionName]);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
var _destroy = function() {
|
|
window.removeEventListener('scroll', _scroll);
|
|
KTUtil.data(the.element).remove('sticky');
|
|
}
|
|
|
|
// Construct Class
|
|
_construct();
|
|
|
|
///////////////////////
|
|
// ** Public API ** //
|
|
///////////////////////
|
|
|
|
// Methods
|
|
the.update = function() {
|
|
if ( document.body.hasAttribute(the.attributeName) === true ) {
|
|
_disable();
|
|
document.body.removeAttribute(the.attributeName);
|
|
document.body.removeAttribute(the.attributeName2);
|
|
_enable(true);
|
|
document.body.setAttribute(the.attributeName, 'on');
|
|
document.body.setAttribute(the.attributeName2, 'on');
|
|
}
|
|
}
|
|
|
|
the.destroy = function() {
|
|
return _destroy();
|
|
}
|
|
|
|
// Event API
|
|
the.on = function(name, handler) {
|
|
return KTEventHandler.on(the.element, name, handler);
|
|
}
|
|
|
|
the.one = function(name, handler) {
|
|
return KTEventHandler.one(the.element, name, handler);
|
|
}
|
|
|
|
the.off = function(name, handlerId) {
|
|
return KTEventHandler.off(the.element, name, handlerId);
|
|
}
|
|
|
|
the.trigger = function(name, event) {
|
|
return KTEventHandler.trigger(the.element, name, event, the, event);
|
|
}
|
|
};
|
|
|
|
// Static methods
|
|
KTSticky.getInstance = function(element) {
|
|
if ( element !== null && KTUtil.data(element).has('sticky') ) {
|
|
return KTUtil.data(element).get('sticky');
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Create instances
|
|
KTSticky.createInstances = function(selector = '[data-kt-sticky="true"]') {
|
|
// Initialize Menus
|
|
var elements = document.body.querySelectorAll(selector);
|
|
var sticky;
|
|
|
|
if ( elements && elements.length > 0 ) {
|
|
for (var i = 0, len = elements.length; i < len; i++) {
|
|
sticky = new KTSticky(elements[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Window resize handler
|
|
KTSticky.handleResize = function() {
|
|
window.addEventListener('resize', function() {
|
|
var timer;
|
|
|
|
KTUtil.throttle(timer, function() {
|
|
// Locate and update Offcanvas instances on window resize
|
|
var elements = document.body.querySelectorAll('[data-kt-sticky="true"]');
|
|
|
|
if ( elements && elements.length > 0 ) {
|
|
for (var i = 0, len = elements.length; i < len; i++) {
|
|
var sticky = KTSticky.getInstance(elements[i]);
|
|
if (sticky) {
|
|
sticky.update();
|
|
}
|
|
}
|
|
}
|
|
}, 200);
|
|
});
|
|
}
|
|
|
|
// Global initialization
|
|
KTSticky.init = function() {
|
|
KTSticky.createInstances();
|
|
|
|
if (KTStickyHandlersInitialized === false) {
|
|
KTSticky.handleResize();
|
|
KTStickyHandlersInitialized = true;
|
|
}
|
|
};
|
|
|
|
// Webpack support
|
|
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
|
module.exports = KTSticky;
|
|
}
|