mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-11-14 20:17:14 +01:00
197 lines
5.9 KiB
JavaScript
197 lines
5.9 KiB
JavaScript
|
|
||
|
/**
|
||
|
* Zum "sticky"-machen von Buttons
|
||
|
*
|
||
|
* @example <a href="#" class="button-sticky">Abschicken</a>
|
||
|
*/
|
||
|
var StickyButton = function ($) {
|
||
|
'use strict';
|
||
|
|
||
|
var me = {
|
||
|
|
||
|
storage: {
|
||
|
$button: null,
|
||
|
$buttonClone: null,
|
||
|
isSticky: false,
|
||
|
isCloned: false,
|
||
|
stickyPositionTop: 0,
|
||
|
stickyPositionRight: 0,
|
||
|
stickyOffsetTopTrigger: 0,
|
||
|
mobileBreakpointWidth: 652,
|
||
|
buffer: null
|
||
|
},
|
||
|
|
||
|
selector: {
|
||
|
target: '.button-sticky',
|
||
|
menuWrapper: '.menu-wrapper'
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Position initial berechnen und EventHandler attachen
|
||
|
*/
|
||
|
init: function () {
|
||
|
me.storage.$button = $(me.selector.target);
|
||
|
if (me.storage.$button.length === 0) {
|
||
|
return;
|
||
|
}
|
||
|
if (me.storage.$button.length > 1) {
|
||
|
console.info('StickyButton wurde deaktiviert. Es darf nur einen StickyButton pro Seite geben.');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Original Button klonen
|
||
|
me.makeClone();
|
||
|
|
||
|
// Initial alle Werte berechnen
|
||
|
me.debounce(me.calculateButtonPosition, 150);
|
||
|
|
||
|
// Event-Handler attachen
|
||
|
$(window).on('scroll', me.onWindowScroll);
|
||
|
$(window).on('resize', me.onWindowResize);
|
||
|
$(document).on('click', '.ui-tabs-anchor', me.calculateButtonPosition);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Button-Position berechnen
|
||
|
*/
|
||
|
calculateButtonPosition: function () {
|
||
|
var windowWidth = $(window).width();
|
||
|
var buttonWidth = me.storage.$buttonClone.outerWidth(true);
|
||
|
var buttonOffset = me.storage.$buttonClone.offset();
|
||
|
var buttonMarginLeft = parseInt(me.storage.$buttonClone.css('margin-left'));
|
||
|
|
||
|
if (typeof buttonOffset !== 'object') {
|
||
|
return;
|
||
|
}
|
||
|
if (buttonOffset.top === 0 && buttonOffset.left === 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var isMobileWindowSize = windowWidth < me.storage.mobileBreakpointWidth;
|
||
|
var menuHeight = isMobileWindowSize ? 0 : $(me.selector.menuWrapper).height();
|
||
|
|
||
|
me.storage.stickyPositionTop = parseInt(menuHeight + 9);
|
||
|
me.storage.stickyPositionRight = parseInt(windowWidth - (buttonOffset.left + buttonWidth) + buttonMarginLeft);
|
||
|
me.storage.stickyOffsetTopTrigger = parseInt(buttonOffset.top - menuHeight - 12);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* EventHandler wenn Größe des Fenster geändert wird
|
||
|
*/
|
||
|
onWindowResize: function () {
|
||
|
me.debounce(me.calculateButtonPosition, 250);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* EventHandler wenn Fenster gescrollt wird
|
||
|
*/
|
||
|
onWindowScroll: function () {
|
||
|
if (!me.storage.isCloned) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var windowScrollPos = this.scrollY;
|
||
|
if (windowScrollPos > me.storage.stickyOffsetTopTrigger) {
|
||
|
if (me.storage.isSticky === false) {
|
||
|
me.makeSticky();
|
||
|
}
|
||
|
} else {
|
||
|
if (me.storage.isSticky === true) {
|
||
|
me.makeUnsticky();
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Button sticky machen
|
||
|
*/
|
||
|
makeSticky: function () {
|
||
|
if (me.storage.stickyPositionTop === 0 &&
|
||
|
me.storage.stickyPositionRight === 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
me.storage.isSticky = true;
|
||
|
me.storage.$button.css({
|
||
|
'display': 'block',
|
||
|
'zIndex': 9999,
|
||
|
'position': 'fixed',
|
||
|
'top': me.storage.stickyPositionTop + 'px',
|
||
|
'right': me.storage.stickyPositionRight + 'px'
|
||
|
});
|
||
|
// Beim Klon nur die Opacity anpassen, damit nichts springt
|
||
|
me.storage.$buttonClone.css({
|
||
|
'opacity': 0
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Button unsticky machen
|
||
|
*/
|
||
|
makeUnsticky: function () {
|
||
|
me.storage.isSticky = false;
|
||
|
me.storage.$button.css({
|
||
|
'display': 'none',
|
||
|
'zIndex': 9999,
|
||
|
'position': 'fixed',
|
||
|
'top': me.storage.stickyPositionTop + 'px',
|
||
|
'right': me.storage.stickyPositionRight + 'px'
|
||
|
});
|
||
|
me.storage.$buttonClone.css({
|
||
|
'opacity': 1
|
||
|
});
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Erstellt einen Klon des Buttons der sticky werden soll
|
||
|
*
|
||
|
* Der Klon ist notwendig als Platzhalter, sonst würden die nebenstehenden Elemente springen.
|
||
|
* Beim "sticky"-machen wird der originale Button eingeblendet und der Klon versteckt.
|
||
|
*/
|
||
|
makeClone: function () {
|
||
|
me.storage.$buttonClone = me.storage.$button.clone();
|
||
|
me.storage.$buttonClone.insertAfter(me.storage.$button);
|
||
|
me.storage.$button.hide();
|
||
|
me.storage.isCloned = true;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @return {boolean}
|
||
|
*/
|
||
|
isVisible: function () {
|
||
|
var buttonVisible = me.storage.$button.is(":visible");
|
||
|
var cloneVisible = me.storage.isCloned ? me.storage.$buttonClone.is(":visible") : false;
|
||
|
|
||
|
return buttonVisible || cloneVisible;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Puffer-Funktion um Events erst nach einer bestimmten Zeit
|
||
|
*
|
||
|
* @param {function} callback
|
||
|
* @param {number} delay
|
||
|
*/
|
||
|
debounce: function (callback, delay) {
|
||
|
var context = this;
|
||
|
var args = arguments;
|
||
|
|
||
|
clearTimeout(me.storage.buffer);
|
||
|
me.storage.buffer = setTimeout(function () {
|
||
|
callback.apply(context, args);
|
||
|
}, delay || 250);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
return {
|
||
|
init: me.init
|
||
|
};
|
||
|
|
||
|
}(jQuery);
|
||
|
|
||
|
/**
|
||
|
* Bestimmte Button "sticky" machen
|
||
|
*/
|
||
|
$(document).ready(function () {
|
||
|
StickyButton.init();
|
||
|
});
|