| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- $(document).ready(function () {
- var $button = $('#back-to-top');
- var $footer = $('footer.footer');
- var $mainColumn = $('.column-main');
- var $leftSidebar = $('.column-left');
- var $rightSidebar = $('.column-right');
- var lastScrollTop = 0;
- var rightMargin = 20;
- var bottomMargin = 20;
- var lastState = null;
- var state = {
- base: {
- classname: 'card has-text-centered',
- left: '',
- width: 64,
- bottom: bottomMargin,
- 'border-radius': 4
- }
- };
- state['desktop-hidden'] = Object.assign({}, state.base, {
- classname: state.base.classname + ' rise-up',
- });
- state['desktop-visible'] = Object.assign({}, state['desktop-hidden'], {
- classname: state['desktop-hidden'].classname + ' fade-in',
- });
- state['desktop-dock'] = Object.assign({}, state['desktop-visible'], {
- classname: state['desktop-visible'].classname + ' fade-in',
- width: 40,
- 'border-radius': '50%'
- });
- state['mobile-hidden'] = Object.assign({}, state.base, {
- classname: state.base.classname + ' fade-in',
- right: rightMargin
- });
- state['mobile-visible'] = Object.assign({}, state['mobile-hidden'], {
- classname: state['mobile-hidden'].classname + ' rise-up',
- });
- function isStateEquals(prev, next) {
- for (var prop in prev) {
- if (!next.hasOwnProperty(prop) || next[prop] !== prev[prop]) {
- return false;
- }
- }
- for (var prop in next) {
- if (!prev.hasOwnProperty(prop) || prev[prop] !== prev[prop]) {
- return false;
- }
- }
- return true;
- }
- function applyState(state) {
- if (lastState !== null && isStateEquals(lastState, state)) {
- return;
- }
- $button.attr('class', state.classname);
- for (let prop in state) {
- if (prop === 'classname') {
- continue;
- }
- $button.css(prop, state[prop]);
- }
- lastState = state;
- }
- function isDesktop() {
- return window.innerWidth >= 1078;
- }
- function isTablet() {
- return window.innerWidth >= 768 && !isDesktop();
- }
- function isScrollUp() {
- return $(window).scrollTop() < lastScrollTop && $(window).scrollTop() > 0;
- }
- function hasLeftSidebar() {
- return $leftSidebar.length > 0;
- }
- function hasRightSidebar() {
- return $rightSidebar.length > 0;
- }
- function getRightSidebarBottom() {
- if (!hasRightSidebar()) {
- return 0;
- }
- return Math.max.apply(null, $rightSidebar.find('.widget').map(function () {
- return $(this).offset().top + $(this).outerHeight(true);
- }));
- }
- function getScrollTop() {
- return $(window).scrollTop();
- }
- function getScrollBottom() {
- return $(window).scrollTop() + $(window).height();
- }
- function getButtonWidth() {
- return $button.outerWidth(true);
- }
- function getButtonHeight() {
- return $button.outerHeight(true);
- }
- function updateScrollTop() {
- lastScrollTop = $(window).scrollTop();
- }
- function update() {
- // desktop mode or tablet mode with only right sidebar enabled
- if (isDesktop() || (isTablet() && !hasLeftSidebar() && hasRightSidebar())) {
- var nextState;
- var padding = ($mainColumn.outerWidth() - $mainColumn.width()) / 2;
- var maxLeft = $(window).width() - getButtonWidth() - rightMargin;
- var maxBottom = $footer.offset().top + getButtonHeight() / 2 + bottomMargin;
- if (getScrollTop() == 0 || getScrollBottom() < getRightSidebarBottom() + padding + getButtonHeight()) {
- nextState = state['desktop-hidden'];
- } else if (getScrollBottom() < maxBottom) {
- nextState = state['desktop-visible'];
- } else {
- nextState = Object.assign({}, state['desktop-dock'], {
- bottom: getScrollBottom() - maxBottom + bottomMargin
- });
- }
- var left = $mainColumn.offset().left + $mainColumn.outerWidth() + padding;
- nextState = Object.assign({}, nextState, {
- left: Math.min(left, maxLeft)
- });
- applyState(nextState);
- } else {
- // mobile and tablet mode
- if (!isScrollUp()) {
- applyState(state['mobile-hidden']);
- } else {
- applyState(state['mobile-visible']);
- }
- updateScrollTop();
- }
- }
- update();
- $(window).resize(update);
- $(window).scroll(update);
- $('#back-to-top').on('click', function () {
- $('body, html').animate({ scrollTop: 0 }, 400);
- });
- });
|