floating-header.js 3.18 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

define([
    'jquery',
    'jquery/ui'
], function ($) {
    'use strict';

    $.widget('mage.floatingHeader', {
        options: {
            placeholderAttrs: {
                'class': 'page-actions-placeholder'
            },
            fixedClass: '_fixed',
            hiddenClass: '_hidden',
            title: '.page-title-wrapper .page-title',
            pageMainActions: '.page-main-actions',
            contains: '[data-role=modal]'
        },

        /**
         * Widget initialization
         * @private
         */
        _create: function () {
            var title = $(this.options.title).text(),
                wrapped = this.element.find('.page-actions-buttons').children();

            if (this.element.parents(this.options.contains).length) {
                return this;
            }

            this._setVars();
            this._bind();
            this.element.find('script').remove();

            if (wrapped.length) {
                wrapped
                    .unwrap()   // .page-actions-buttons
                    .unwrap();  // .page-actions-inner
            }
            this.element.wrapInner($('<div/>', {
                'class': 'page-actions-buttons'
            }));
            this.element.wrapInner($('<div/>', {
                'class': 'page-actions-inner', 'data-title': title
            }));
        },

        /**
         * Set privat variables on load, for performance purposes
         * @private
         */
        _setVars: function () {
            this._placeholder = this.element.before($('<div/>', this.options.placeholderAttrs)).prev();
            this._offsetTop = this._placeholder.offset().top;
            this._height = this.element
                .parents(this.options.pageMainActions)
                .outerHeight();
        },

        /**
         * Event binding, will monitor scroll and resize events (resize events left for backward compat)
         * @private
         */
        _bind: function () {
            this._on(window, {
                scroll: this._handlePageScroll,
                resize: this._handlePageScroll
            });
        },

        /**
         * Event handler for setting fixed positioning
         * @private
         */
        _handlePageScroll: function () {
            var isActive = $(window).scrollTop() > this._offsetTop;

            if (isActive) {
                this.element
                    .addClass(this.options.fixedClass)
                    .parents(this.options.pageMainActions)
                    .addClass(this.options.hiddenClass);
            } else {
                this.element
                    .removeClass(this.options.fixedClass)
                    .parents(this.options.pageMainActions)
                    .removeClass(this.options.hiddenClass);
            }

            this._placeholder.height(isActive ? this._height : '');
        },

        /**
         * Widget destroy functionality
         * @private
         */
        _destroy: function () {
            this._placeholder.remove();
            this._off($(window));
        }
    });

    return $.mage.floatingHeader;
});