4

Update:

The problem occurred again and gave me a chance to check a few more things. The script is loaded and the contents can be viewed in Chrome's developer tools under the "Sources" panel.

This means that it is being loaded, but it is not being executed.

jQuery is available on that page publicly and I was trying to pass it through as a dependency into the call back as jQuery

Since the function is anonymous - there should be no conflict here - no?

My proof is that this works and logs the response from the ajax query. Is requireJs refusing to use it with that name since the global variable already exists for that parameter? jQuery.ajax('/', function(jQuery) { console.log(jQuery); });


Original Post:

It is very important that I understand why this is happening and how to get around it.

I am avoiding the use of the $ sign for jQuery everywhere in my scripts and loading all of them through requirejs.

There are many buttons that have event listeners attached to them that work nearly all of the time - however sometimes when the page loads the events do not fire or may never be binded to the elements.

I don't know if it's a requirejs problem or jquery conflict. Has anyone else dealt with this yet?

Config:

var config = {
    map: {
        '*': {
            footerContact: 'Module_Contact/js/contact',
        }
    }
};

Script (contact.js)

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

    jquery('.element').on('click', function(event) {
    });
});

phtml include:

<script type="text/javascript">
  require(['footerContact']);
</script>

Edit:

I am not convinced it is a requirejs shim issue, reading the documentation it states the criteria for using shim config:

Ideally the scripts you load will be modules that are defined by calling define(). However, you may need to use some traditional/legacy "browser globals" scripts that do not express their dependencies via define(). For those, you can use the shim config. To properly express their dependencies.

Yet my script uses define to include its dependencies...

6
  • 2
    please add your js code to more debug Nov 24, 2016 at 9:57
  • I have updated answer you can check at last. Remove var folder and clear cache. check your changes Nov 24, 2016 at 10:39
  • Yes, thank you. Testing now, how do you know when to use shim? Nov 24, 2016 at 10:41
  • I have occur same type of issue in past so many times so i have debug requirejs, using shim of requirejs and after that used of shim, No more issue are available of some time load or some times not load. Nov 24, 2016 at 10:46
  • 1
    Please let me know if you have problem are still occur Nov 24, 2016 at 10:51

2 Answers 2

3
+25

You have to set jQuery dependency for your custom script. You have occurance of problem because of dependency issue.

  1. For Module/Extension Level

You can set at module/extension level dependency like below,

app/code/Packagename/Modulename/view/frontend/requirejs-config.js

var config = {
    paths: {            
            'slider': "Packagename_Modulename/js/slider"
        },   
    shim: {
        'slider': {
            deps: ['jquery']
        }
    }
};

Add slider.js inside path, app/code/Packagename/Modulename/view/frontend/web/js/slider.js

You can use in any template file like this,

<script>
    require(["jquery","slider"],function($)(){
        $(document).ready(function() {
            $(element).slider({
                   //option
            });
        });
    });
</script>
  1. Theme Level

If you want to apply require js changes at theme level, Go to theme module,

app/design/frontend/{Packagename}/{themename}/Packagename_Modulename/requirejs-config.js

Set your theme required js file in requirejs-config.js

var config = {
    paths: {            
            'slider': "Packagename_Modulename/js/slider",
            'customjsfile': "Packagename_Modulename/js/customjsfile",
        },   
    shim: {
        'slider': {
            deps: ['jquery']
        },
        'customjsfile':{
            deps: ['jquery']
        }
    }
};

Add your js file inside web folder of theme,

app/design/frontend/{Packagename}/{themename}/Packagename_Modulename/web/js/slider.js
app/design/frontend/{Packagename}/{themename}/Packagename_Modulename/web/js/customjsfile.js

In your template file,

<script>
    require(["jquery","slider","customjsfile"],function($)(){
        $(document).ready(function() {
            $(element).slider({
                   //option
            });
        });
    });
</script>

For your case,

Keep below config in requirejs-config.js file,

var config = {
    paths: {            
            'footerContact': 'Module_Contact/js/contact'
        },   
    shim: {
        'footerContact': {
            deps: ['jquery']
        }
    }
};

Inside phtml file,

<script>
  require(["jquery","footerContact"],function($)(){
    jquery('.element').on('click', function(event) {
        console.log('logging');
    });
  });
</script>
7
  • I'm sorry but I don't understand how this relates to event listeners not firing? Nov 24, 2016 at 10:16
  • So if you don't set the dependency it works sometimes but not always...? Nov 24, 2016 at 10:17
  • 1
    yes because of requirejs used AMD. so some time other js are loaded before our main js and dependancy are not ordered so we have to set dependancy for our js to prevent those type of changes. Nov 24, 2016 at 10:22
  • Is this because jquery isn't a real requirejs module? Nov 24, 2016 at 10:25
  • you have to load jquery in requirejs parameter under your template. Nov 24, 2016 at 10:28
1

Try including your scripts the declarative way instead.

If you are targeting a specific element, apply the data-mage-init attribute:

<button data-mage-init='{"footerContact":{}}'>Click Me</button>

If you are binding to a group of elements, use the text/x-magento-init script tag:

<script type="text/x-magento-init">
{
    ".someCssSelector": {
        "footerContact": {}
    }
}
</script>

in the corresponding js file:

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

    return function (config, element) {
        $(element).click(function (e) {
            // do something
        });
    };
});
3
  • Sounds good. What if I'm not binding to an element? Do you have an option for that - or is that what could be causng my problems? Nov 24, 2016 at 12:00
  • 1
    You would use "*" as the selector. Nov 24, 2016 at 12:36
  • The two solutions I've had will take a while to test, bear with me. Thank you for your input. Nov 24, 2016 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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