Nowadays you can’t imagine an online store without dynamic, changing elements. They are a great way to stand out among your competitors and add individuality to your shop. JavaScript is considered the best tool for including such elements. Magento 2 allows to connect custom scripts for the entire site, certain pages, or even for specified blocks and parts of a page.
What options exist to include custom JavaScript on a page?
What are the advantages and disadvantages of inline JavaScript?
How can JavaScript be loaded asynchronously on a page?
How can JavaScript on a page be configured using block arguments in layout XML?
How can it be done directly in a .phtml template?
What options exist to include custom JavaScript on a page?
You can do this three ways: by connecting scripts to the head of a page, through a special engine framework, or with the help of RequireJS (the most preferred option). Let’s consider the first way – the connection of scripts to the head of a page. Bear in mind, that if you resort to his method, it will be impossible to override classes in the script and any user interaction will be minimized. Perhaps this method is the most suitable in the case when you connect via cdn of known libraries, or if you use a third-party aggregator for your scripts.
The connection process looks the following way:
1 |
<script src=”absolute or relative path to the script” ></script> |
if the path is absolute, use
1 |
src_type="url" |
or
1 |
<script type="text/javascript">script content</script> |
inline in phtml.
To improve this method, try to use deferred=”true” attribute or at least async=”true” where you can (however it is applicable only for scripts by reference and won’t work for inline scripts). What is more, instead of
1 |
<script src="js/script.js"/> |
you can use
1 |
<link src="js/script.js"/> |
Now let’s proceed to the second method – through Magento framework. You can include the script two ways:
- Using the following attribute
1data-mage-init='{ "VendorName_Module/js/script": {"configuration-value":true} }'
It will request a script with the element it will work with and its parameters (animation speed, number of elements, etc).
The final form of the script will be the following:
1 2 3 4 5 6 7 8 |
app/code/VendorName/Module/view/frontend/web/js/script.js define([], function() { return function(element, config) { /* config: { configuration-value: true } */ }; }); |
- Using tag script
1234567<script type="script/x-magento-init">{".element-selector":{"VendorName_Module/js/script":{"configuration-value": true}}}</script>
where .element-selector is the selector for which the module will be applied. If the selector matches to not one, but a couple of elements, it will be applied to each of them.
Connecting a script that depends on a third-party library is not the most correct, but undoubtedly easy way:
1 2 3 4 5 6 7 |
<script type="text/javascript"> require([ "VendorName_Module/js/script" //<span style="font-weight: 400;">indicate library dependence</span> ], function(loader) { /* your script */ }); </script> |
The third method is through RequireJS.
This way allows to connect the script to any page and works faster than the first two, because you need less code for initialization.
1 2 3 |
var config = { deps: ['VendorName_Module/js/script'] }; |
What are the advantages and disadvantages of inline JavaScript?
Among the advantages of inline JS we can name the following:
- Easy to connect
- No additional request on the page
Yet there are disadvantages to this method, because the code:
- is not delayed and executed immediately, so it is not recommended to place a large inline code;
- is hard to use again; you’ll have to insert it again for another pages;
- is hard to find in the templates, which is why it is difficult to maintain;
- is not cached by the browser for it is part of the page;
- defies Content-Security-Policy, which makes it dangerous in terms of cross-site scripting.
How can JavaScript be loaded asynchronously on a page?
This can be done through define method.
Require is immediately executed, while define will be waiting for the call from other modules. For example:
1 2 3 4 5 |
require([ 'VendorName_Module/js/script' ], function(nameFunction) { /* … */ }); |
You can also delay loading with the help of modules. For example, Defer for Magento module is great for improving the load time and overall site optimization. You can download Defer here.
Magento Development Services
Take your online store to the next level with BelVG Magento development
Click to visit the pageHow can JavaScript on a page be configured using block arguments in layout XML?
In AbstractBlock there is a getJsLayout method, which returns the array with jsLayout – parameters. In the frontend
1 |
<?= $block->getJsLayout();?> |
will return us a line in json format, built from jsLayout.
Consequently, using <arguments/>, you can build your own json object:
1 2 3 4 5 6 7 8 9 10 |
<referenceBlock name="nameBlock"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="script" xsi:type="array"> <item name="component" xsi:type="string">VendorName_Module/js/script</item> </item></item> </argument> </arguments> </referenceBlock> |
So this is all for this topic. I hope my article was useful; if you have any questions or comments, please leave it down below!
Looking for an expert Magento 2 development team? Turn to BelVG!
Neet, clear and TO THE POINT explanation. Good Job!