Magento – Best practice for calling JavaScript on a specific page in Magento2

javascriptmagento2requirejs

I would like to initialize a jQuery carousel plugin on the product details page, the slide carousel.

I've found two ways to do it, but am wondering if there is a better way.

First off, I added the script to the plugin to my theme's require-config.js file with:

// app/design/frontend///require-config.js
var config = {

// When load 'requirejs' always load the following files also
deps: [
    "js/main" // path to main.js script
],
paths: {
    'slick': 'js/vendor/jquery/slick.min' // path to script in my theme
},
shim: {
    'slick': {
        deps: ['jquery'],
        exports: 'jQuery.fn.slick'
    }
}

};

Then I found that I could initialise the carousel in my main.js with:

define([
        "jquery",
        "slick"
    ],
    function($) {
        "use strict";

        $('.products-related .product-items').slick();

        return;
    }
);

But this approach means the slick.min.js file is loaded on every page, and $('.products-related .product-items').slick(); is executed on every page.

I could initialize the script only on the product details page by adding the following <script> tag to app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml

<script>
    require([
        "jquery",
        "slick"
    ], function ($) {
        $('.products-related .product-items').slick();
    });
</script>

But this means I need to override a template file and use an inline script, is there a better way? Where I would load an external script just on the product details page?

It probably has little performance impact if I just add it to main.js which is easier but I'm just curious.

Thanks!

Best Answer

You can use data-mage-init for call Widget Js in template

First extend layout catalog_product_view to your theme layout dir (Don't edit core files)

Add attribute data-mage-init to div wrap you want to slide

<ol class="products list slider items product-items" data-mage-init='{"SlickSlide": {}}'> 
  // Slide content here
</ol>


Here is requirejs-config.js

var config = {
   map: {
       '*': {
          'SlickSlide' :  'js/init',
          'slick' :  'js/slick.min',

       }
   },
};

File init.js just simple widget standard of magento to init your lib

define([
'jquery',
'slick',
], function (jQuery, slick) {
'use strict';

jQuery.widget('mage.Slick', {
    options: {
        "test": 111// HERE YOU CAN PASS ANY PARAMETERS
    },

    /**
     * Initialize widget
     */
    _create: function () {
        var self = this,
            slick;

        console.log('test');
        jQuery(".product-items").slick({
            dots: true,
            infinite: true,
            slidesToShow: 3,
            slidesToScroll: 3
        });

    },

});

return jQuery.mage.Slick;

});
Related Topic