5

I'm trying to inject a scroll to anchor javascript globally in Magento 2.

More specifically this script:

$('a[href^="#"]').on('click', function(event) {
    var target = $(this.getAttribute('href'));
    if( target.length ) {
        event.preventDefault();
        $('html, body').stop().animate({
            scrollTop: target.offset().top
        }, 1000);
    }
});

I have taken the reference from this blog post.

I converted it to include defines and stuff:

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

$('a[href^="#"]').on('click', function(event) {
    var target = $(this.getAttribute('href'));
    if( target.length ) {
        event.preventDefault();
        $('html, body').stop().animate({
            scrollTop: target.offset().top
        }, 1000);
    }
});

});

And injecting it in to my themes default_head_blocks.xml with <link src="js/custom.js" />

The injection works but I am getting the following error in Chrome console:

Uncaught Error: Mismatched anonymous define() module: function ($) {
    'use strict';

require.js:166
4

Instead of defined use require Like this:

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

    $('a[href^="#"]').on('click', function(event) {
        var target = $(this.getAttribute('href'));
        if( target.length ) {
            event.preventDefault();
            $('html, body').stop().animate({
                scrollTop: target.offset().top
            }, 1000);
        }
    });
});
  • 2
    Don't know if it's the best way, but it worked and I didn't have to touch the header file. – John Mar 8 at 5:08
  • Yes, it is the way of Magento to write js anywhere in your code. using define includes the files that you add in it – Shoaib Munir Mar 8 at 5:10
3

Add an external JS in the following way :

Try this,

Add your custom js in the following path.

app/design/frontend/Vendor/theme-name/web/js/nameofjs.js

then you need to add requirejs-config.js to the following path.

app/design/frontend/Vendor/theme-name/requirejs-config.js

then add the following code in it

 var config = {
    paths: {            
            'your_js_name' : 'js/nameofjs', 
        },                                                                
    shim: {
    'your_js_name': {
        deps: ['jquery']
    },
  }
};

and add the below code to load custom js, In your case it would be header.phtml in Magento_Theme folder in your theme

app/design/frontend/Vendor/theme-name/Magento_Theme/templates/html/header.phtml

<script>
require(['jquery','your_js_name'],function($) {
$(window).load(function () {
     /*alert('load from external jquery');*/
});});
</script>

Hope this helps and this is correct way to load any custom js in M2 as far as I know.

Peace :)

  • Nice one Prathap, you elaborate well, how to add js. +1 – Shoaib Munir Mar 8 at 4:36
  • Do the above things and it will add js when the script loaded – Prathap Gunasekaran Mar 8 at 4:39
  • See this get more about how js is loading in magento 2 magento.stackexchange.com/questions/264679/… – Prathap Gunasekaran Mar 8 at 4:40
  • I have to override the header.phtml template? Where in that file does the code go? – John Mar 8 at 4:45
  • Your header.phtml must be in this path app/design/frontend/Vendor/theme-name/Magento_Theme/templates/html/header.phtml – Prathap Gunasekaran Mar 8 at 4:47
1

In Maggento 2 the concept of requirejs is restricting you to add the an external js which is not bound into any module. So what you can do is simply create a custom module follow this & define your js there into that module at below location

Magento_root/app/code/Vendor/Module/view/frontend/web/js/file.js

It should contains the code as follows

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

    $('a[href^="#"]').on('click', function(event) {
        var target = $(this.getAttribute('href'));
        if( target.length ) {
            event.preventDefault();
            $('html, body').stop().animate({
                scrollTop: target.offset().top
            }, 1000);
        }
    });
});

Define it into your requirejs-config.js located at below location

Magento_root/app/code/Vendor/Module/view/frontend/requirejs-config.js

It should Contains the code as follows:

var config = {
    map: {
        '*': {
            module_js_denotation_name: 'Vendor_module/js/file',
        }
    }
};

Now you can call it into any phtml file you want to load it as follows

<script type="text/javascript">
    require(['jquery', 'module_js_denotation_name'], function($, myscript) {
        myscript();
    });
</script>

For your requirement you need to call it into the header.phtml or the footer.phtml file.

You can also create your own phtml file at Vendor/Module/view/frontend/template/template.phtml & call it there & with the help of layout Vendor/Module/view/frontend/layout/default.xaml file you can inject your template file to the theme (I am supposing that you no how to inject your phtml to your theme through the layout files).

Note: Make sure after doing this you are running the below commands o register your module & deploy the contents & make sure you are not making any changes to the default magento file always make the changes to your custome code that is inside the Magento_root/app directory

php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.