Christopher Dosin

jQuery sticky element / menu for Shopware

January 05, 2019

This article is about how to write a very basic jQuery Plugin for Shopware to get a sticky element based on the scroll position. For example we can apply our plugin to our menu to get a sticky menu within our Theme.

The cool thing: We don’t need any third party plugin! Yiha. Let’s get started.

First things first: We need to create our very basic plugin class. I call the plugin swStickyElement, but it’s up to you how you name your plugin.

$.plugin('swStickyElement', {})

Now we need to define our default properties, which we can also modify with the HTML data attribute.

$.plugin('swStickyElement', {
  defaults: {
    /**
     * The css class for the sticky element.
     *
     * @property stickyCls
     * @type {String}
     */
    stickyCls: 'is--sticky',

    /**
     * The element which applies to the exceptCls class
     *
     * @property exceptElement
     * @type {String}
     */
    exceptElement: 'body',

    /**
     * The css classes of the exceptElement
     * to disable the sticky function
     *
     * @property exceptClasses
     * @type {String}
     */
    exceptClasses: '.is--ctl-checkout, .is--target-checkout',

    /**
     * The scroll position
     *
     * @property 100
     * @type {Integer}
     */
    scrollTop: 100,
  },
})

Our default object contains now a few basic properties which we need in our plugin. The first property is stickyCls which is our CSS class which will be applied to the element, once we reached our scroll position.

Then we have the exceptElement property which we need to grab our element. In this case we’re grabing the <body> element. With the exceptClasses property, we’re defining our CSS classes to disable the sticky function, if there is the specific class.

In Shopware the class is--ctl-checkout is applied to the body element once we’re on the checkout page for example. Because our user should focus on the basket, we’re disabling the sticky element on this page.

Last but not least we have the scrollTop property, which defines after how many pixels from the top the stickyCls will be applied.

Now we need to initialize our function

/**
 * Initializes the plugin
 *
 * @public
 * @method init
 */
init: function() {
    var me = this;

    me.applyDataAttributes();

    me.sticky();
},

The applyDataAttributes method applies the default properties which we created before to the element. Then we call thesticky() method which we will create now.

/**
   * Add's the css class based on the given scroll position
   *
   * @public
   * @method sticky
   * @returns {jQuery}
   */
sticky: function() {
    var me = this;

    if (!$(me.opts.exceptElement).is(me.opts.exceptClasses)) {
        $(window).scroll(function() {
        if ($(window).scrollTop() >= me.opts.scrollTop) {
            $(me.$el).addClass(me.opts.stickyCls);
        } else {
            $(me.$el).removeClass(me.opts.stickyCls);
        }
        });
    }
},

Let’s break it down: First we check if we can find the exceptElement (body) with the CSS classes exceptClasses ( .is—ctl-checkout & .is—target-checkout ) on the current page. If one of the classes exist on the body element the IF statement will not be executed.

Then we grab the browsers window and get the current scroll position. If the scrollposition is equal or more then we defined in our scrollTop property, then we grab the element and add the CSS class which we defined in our stickyCls property.

If the scrollpoisiton is less then scrollTop we remove the CSS class which we defined in stickyCls.

Last but not least, we need to destroy our plugin, for example when we’re leaving a viewport and Shopware’s State Manager will destroy the plugin.

/**
 * Destroys the plugin and all necessary settings.
 *
 * @public
 * @method destroy
 */
destroy: function() {
    var me = this;

    $(me.$el).removeClass(me.opts.stickyCls);
    me._destroy();
}

Now we just need to register our plugin within the StateManager.

/**
 * Register the Plugin to the Statemanager
 */
StateManager.addPlugin('*[data-sticky-element="true"]', 'swStickyElement')

If you want to adjust the scroll position for example within your HTML code, you can archive this with the HTML data attributes. Just add data-scrollTop="200" to your HTML element to set the scrollTop property to 200px.


Christopher Dosin

I am a Fullstack Javascript Developer and a digital nomad trying to build useful things. You should follow me on Twitter