160 lines
4.8 KiB
JavaScript
Executable File
160 lines
4.8 KiB
JavaScript
Executable File
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
define([
|
|
'jquery',
|
|
'jquery-ui-modules/widget'
|
|
], function ($) {
|
|
'use strict';
|
|
|
|
$.widget('mage.sticky', {
|
|
options: {
|
|
/**
|
|
* Element selector, who's height will be used to restrict the
|
|
* maximum offsetTop position of the stuck element.
|
|
* Default uses document body.
|
|
* @type {String}
|
|
*/
|
|
container: '',
|
|
|
|
/**
|
|
* Spacing in pixels above the stuck element
|
|
* @type {Number|Function} Number or Function that will return a Number
|
|
*/
|
|
spacingTop: 0,
|
|
|
|
/**
|
|
* Allows postponing sticking, until element will go out of the
|
|
* screen for the number of pixels.
|
|
* @type {Number|Function} Number or Function that will return a Number
|
|
*/
|
|
stickAfter: 0,
|
|
|
|
/**
|
|
* CSS class for active sticky state
|
|
* @type {String}
|
|
*/
|
|
stickyClass: '_sticky'
|
|
},
|
|
|
|
/**
|
|
* Retrieve option value
|
|
* @param {String} option
|
|
* @return {*}
|
|
* @private
|
|
*/
|
|
_getOptionValue: function (option) {
|
|
var value = this.options[option] || 0;
|
|
|
|
if (typeof value === 'function') {
|
|
value = this.options[option]();
|
|
}
|
|
|
|
return value;
|
|
},
|
|
|
|
/**
|
|
* Bind handlers to scroll event
|
|
* @private
|
|
*/
|
|
_create: function () {
|
|
$(window).on({
|
|
'scroll': $.proxy(this._stick, this),
|
|
'resize': $.proxy(this.reset, this)
|
|
});
|
|
|
|
this.element.on('dimensionsChanged', $.proxy(this.reset, this));
|
|
|
|
this.reset();
|
|
|
|
// Application of the workaround for IE11 and Edge
|
|
this.normalizeIE11AndEdgeScroll();
|
|
},
|
|
|
|
/**
|
|
* float Block on windowScroll
|
|
* @private
|
|
*/
|
|
_stick: function () {
|
|
var offset,
|
|
isStatic,
|
|
stuck,
|
|
stickAfter;
|
|
|
|
isStatic = this.element.css('position') === 'static';
|
|
|
|
if (!isStatic && this.element.is(':visible')) {
|
|
offset = $(document).scrollTop() -
|
|
this.parentOffset +
|
|
this._getOptionValue('spacingTop');
|
|
|
|
offset = Math.max(0, Math.min(offset, this.maxOffset));
|
|
|
|
stuck = this.element.hasClass(this.options.stickyClass);
|
|
stickAfter = this._getOptionValue('stickAfter');
|
|
|
|
if (offset && !stuck && offset < stickAfter) {
|
|
offset = 0;
|
|
}
|
|
|
|
this.element
|
|
.toggleClass(this.options.stickyClass, offset > 0)
|
|
.css('top', offset);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Defines maximum offset value of the element.
|
|
* @private
|
|
*/
|
|
_calculateDimens: function () {
|
|
var $parent = this.element.parent(),
|
|
topMargin = parseInt(this.element.css('margin-top'), 10),
|
|
parentHeight = $parent.height() - topMargin,
|
|
height = this.element.innerHeight(),
|
|
maxScroll = document.body.offsetHeight - window.innerHeight;
|
|
|
|
if (this.options.container.length > 0) {
|
|
maxScroll = $(this.options.container).height();
|
|
}
|
|
|
|
this.parentOffset = $parent.offset().top + topMargin;
|
|
this.maxOffset = maxScroll - this.parentOffset;
|
|
|
|
if (this.maxOffset + height >= parentHeight) {
|
|
this.maxOffset = parentHeight - height;
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Facade method that places sticky element where it should be.
|
|
*/
|
|
reset: function () {
|
|
this._calculateDimens()
|
|
._stick();
|
|
},
|
|
|
|
/**
|
|
* Workaround for IE11 and Edge that solves the IE known rendering issue
|
|
* that prevents sticky element from jumpy movement on scrolling the page.
|
|
*
|
|
* Alternatively, undesired jumpy movement can be eliminated by changing the setting in IE:
|
|
* Settings > Internet options > Advanced tab > inside 'Browsing' item > set 'Use smooth scrolling' to False
|
|
*/
|
|
normalizeIE11AndEdgeScroll: function () {
|
|
if (navigator.userAgent.match(/Trident.*rv[ :]*11\.|Edge\//)) {
|
|
document.body.addEventListener('mousewheel', function () {
|
|
event.preventDefault();
|
|
window.scrollTo(0, window.pageYOffset - event.wheelDelta);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
return $.mage.sticky;
|
|
});
|