Files
postshop-backend/public/web/shella/scripts/module.sticky-header.js
2026-02-03 15:31:29 +05:00

221 lines
8.0 KiB
JavaScript

theme.StickyHeader = function() {
function StickyHeader() {
};
StickyHeader.prototype = $.extend({}, StickyHeader.prototype, {
init: function($sticky, params) {
var effect = $sticky.attr('data-sticky-effect') || 1;
if ($sticky.length) {
var stickyHeader = {
_create: function() {
var _ = this,
$elem = this.bindings,
$sticky_m = $elem.find(this.options.mobile && this.options.mobile.sticky ? this.options.mobile.sticky : ''),
$sticky_d = $elem.find(this.options.desktop && this.options.desktop.sticky ? this.options.desktop.sticky : ''),
$spacer_m = $('<div>').addClass('header__spacer header__spacer--m').insertBefore($sticky_m),
$spacer_d = $('<div>').addClass('header__spacer header__spacer--d').insertBefore($sticky_d);
this.sticky_class = 'header__content--sticky';
function fix() {
_._fix(_.$sticky, _.$spacer);
_._move(_.options[_.bp]);
};
function unfix() {
_._unfix(_.$sticky, _.$spacer);
_._return(_.options[_.bp]);
};
function on_resize() {
var is_desktop = theme.current.is_desktop;
_.bp = is_desktop ? 'desktop' : 'mobile';
_.$sticky = is_desktop ? $sticky_d : $sticky_m;
_.$spacer = is_desktop ? $spacer_d : $spacer_m;
if(!_.$sticky.length) return;
if (is_desktop) {
$spacer_m.removeClass('header__spacer--visible');
$spacer_d.addClass('header__spacer--visible');
if ($sticky_m.hasClass(_.sticky_class)) {
_._unfix($sticky_m, $spacer_m);
_._return(_.options.mobile);
}
} else {
$spacer_d.removeClass('header__spacer--visible');
$spacer_m.addClass('header__spacer--visible');
if ($sticky_d.hasClass(_.sticky_class)) {
_._unfix($sticky_d, $spacer_d);
_._return(_.options.desktop);
}
}
};
function on_scroll() {
if(!_.$sticky.length) return;
var limit = _.options[_.bp].limit ? _.options[_.bp].limit : 0,
spacer_pos = _.$spacer[0].getBoundingClientRect();
if (limit === 'bottom') {
limit = _.$sticky.hasClass(_.sticky_class) ? _.$spacer.innerHeight() : _.$sticky.innerHeight();
}
limit *= -1;
if (spacer_pos.top < limit) {
if (!_.$sticky.hasClass(_.sticky_class)) {
fix();
}
if(!ie) {
_._check_height(_.$sticky, _.options[_.bp]);
}
} else {
if (_.$sticky.hasClass(_.sticky_class)) {
unfix();
}
}
};
on_resize();
on_scroll();
$window.on({
'theme.resize.stickyHeader': function() {
on_resize();
on_scroll();
},
'scroll.stickyHeader': on_scroll
});
},
_fix: function($sticky, $spacer) {
var height = $sticky.innerHeight();
$spacer.height(height);
if(this.options[this.bp].fade) {
$sticky.css({ 'opacity': 0 }).velocity({ 'opacity': theme.animations.sticky_header.opacity }, this.options[this.bp].duration());
}
$sticky.addClass(this.sticky_class);
},
_unfix: function($sticky, $spacer) {
$spacer.removeAttr('style');
if(this.options[this.bp].fade) {
$sticky.velocity('stop', true);
}
$sticky.removeAttr('style').removeClass(this.sticky_class);
},
_move: function(obj) {
if (!obj.move) return;
$.each(obj.move, function() {
var $elem = $(this.elem),
$to = $(this.to),
method = this.method || 'append';
this.$elem = $elem;
this.$parent = $elem.parent();
$to[method]($elem);
});
},
_return: function(obj) {
if (!obj.move) return;
$.each(obj.move, function() {
var method = this.method || 'append';
this.$parent[method](this.$elem);
this.$elem = null;
this.$parent = null;
});
},
_check_height: function($sticky, obj) {
if(!obj.height) return;
var spacer_pos = this.$spacer[0].getBoundingClientRect(),
height = spacer_pos.bottom <= obj.height ? obj.height : spacer_pos.bottom;
$sticky.css({ 'min-height': height });
},
getStickyHeight: function() {
return this.options[this.bp] ? (this.options[this.bp].height || $(this.options[this.bp].sticky).innerHeight()) : 0;
},
destroy: function() {
$(window).unbind('resize.stickyHeader scroll.stickyHeader');
$.Widget.prototype.destroy.call(this);
}
};
$.widget('ui.stickyHeader', stickyHeader);
$sticky.stickyHeader(params);
this.$sticky = $sticky;
return {
destroy: function() {
$sticky.stickyHeader('destroy');
}
};
}
}
});
theme.StickyHeader = new StickyHeader;
};
$(function() {
theme.StickyHeader();
});
/*DOCUMENTATION*/
//params example
/*
{
bp: 1024,
mobile: {
sticky: '.tt-header__nav',
limit: 400,
fade: true,
duration: 400
},
desktop: {
sticky: '.tt-header__menu',
height: 60,
move: [
{
elem: '.tt-header__sidebar',
to: '.tt-header__menu',
method: 'append'
}
]
}
}
//params info
bp - responsive breakpoint (number)
mobile, desktop - breakpoint params (object)
bp.sticky - sticky element (selector)
bp.limit - breakpoint to start sticky (number, 'bottom')
bp.height - change sticky element height (number)
bp.fade - fade effect (bool)
bp.duration - effects duration (number)
bp.move - move elements inside sticky (array of objects)
bp.move.elem - items that are moved (selector)
bp.move.to - element to which to move (selector)
bp.move.method - jquery method move (string)
*/