layout | group | subgroup | title | menu_title | menu_order | version | github_link | redirect_from | ||
---|---|---|---|---|---|---|---|---|---|---|
default |
jsdg |
1_Javascript |
Calling and initializing JavaScript |
Calling and initializing JavaScript |
2 |
2.0 |
javascript-dev-guide/javascript/js_init.md |
|
This topic talks about how to insert a JavaScript component in .phtml
page templates and .js
files in Magento 2.
It covers declarative notation, used when initialization is required, and imperative notation, used in other cases.
We strongly recommend that you use the described approaches and do not add inline JavaScript.
Depending on your task, you might want to use declarative or imperative notation. Both ways are described in the following sections.
Using the declarative notation to insert a JS component allows preparing all the configuration on the backend side and outputting it to the page source using standard tools. You should use declarative notation if your JavaScript component requires initialization.
In Magento 2 there are two ways of declarative notation:
- using the
data-mage-init
attribute - using the
<script type="text/x-magento-init" />
tag
Both ways are described further.
Use the data-mage-init
attribute to insert a JS component in a certain HTML element. The following code sample is an illustration. Here a JS component is inserted in the <nav/>
element:
<nav data-mage-init='{ "<component_name>": {...} }'></nav>
When inserted in a certain element, the script is called only for this particular element. It is not automatically called for other elements of this type on the page.
On DOM ready, the data-mage-init
attribute is parsed to extract components' names and configuration to be applied to the element.
Depending on the type of the inserted JS component, processing is performed as follows:
- If an object is returned, the initializer tries to find the
<component_name>
key. If the corresponding value is a function, the initializer passes theconfig
andelement
values to this function.For example:
return { '<component_name>': function(config, element) { ... } };
- If a function is returned, the initializer passes the
config
andelement
values to this function.For example:
return function(config, element) { ... };
- If neither a function nor an object with the
"<component_name>"
key are returned, then the initializer tries to search for"<component_name>"
in the jQuery prototype. If found, the initializer applies it as$(element).<component_name>(config)
.For example:
$.fn.<component_name> = function() { ... }; return;
- If none of the previous cases is true, the component is executed with no further processing.
Such a component does not require either
config
orelement
. The recommended way to declare such components is using the <script> tag.
To call a JS component on a HTML element without direct access to the element or with no relation to a certain element, use the <script type="text/x-magento-init">
tag and attribute. The syntax is following:
{%highlight html%}
<script type="text/x-magento-init"> { // components initialized on the element defined by selector "": { "": ..., "": ... }, // components initialized without binding to an element "*": { "": ... } } </script>{%endhighlight%}
Where:
<element_selector>
is a selector (in terms of querySelectorAll) for the element on which the following JS components are called.<js_component1>
and<js_component2>
are the JS components being initialized on the element with the selector specified as<element_selector>
.<js_component3>
is the JS component called with no binding to an element.
The following is a working code sample of a widget call using <script>
. Here the accordion
and navigation
widgets are added to the element with the #main-container
selector, and the pageCache
script is inserted with no binding to any element.
{%highlight html%}
<script type="text/x-magento-init"> { "#main-container": { "navigation": getNavigationConfig(); ?>, "accordion": getNavigationAccordionConfig(); ?> }, "*": { "pageCache": getPageCacheConfig(); ?> } } </script>{%endhighlight%}
Imperative notation allows using raw JavaScript code on the pages and executing particular business logic. The notation using the <script>
tag, without the type="text/x-magento-init
attribute, is the imperative notation. The syntax is following:
{%highlight html%}
<script> require([ 'jquery', 'accordion' // the alias for "mage/accordion" ], function ($) { $(function () { // to ensure that code evaluates on page load $('[data-role=example]') // we expect that page contains the .. markup .accordion({ // now we can use "accordion" as jQuery plugin header: '[data-role=header]', content: '[data-role=content]', trigger: '[data-role=trigger]', ajaxUrlElement: "a" }); }); }); </script>{%endhighlight%}
To call a widget in JS code, use a notation similar to the following (accordion widget is intiialized on the [data-role=example]
element as illustration):
{%highlight js%}
$('[data-role=example]').accordion();
{%endhighlight%}
To initialize a widget with options, use notation similar to the following:
{%highlight js%}
{% endhighlight %}
In a similar way, you can initialize any JS component that a returns callback function accepting a config
object and element
(a DOM node).
For example:
{%highlight js%} define ([ 'jquery', 'mage/gallery/gallery' ], function ($, Gallery) {
$(function () { // to ensure that code evaluates on page load
$('[data-role=example]') // we expect that page contains markup <tag data-role="example">..</tag>
.each(function (index, element) {
Gallery({
options: {},
data: [{
img: 'https://c2.staticflickr.com/8/7077/27935031965_facd03b4cb_b_d.jpg'
}],
fullscreen: {}
}, element); // 'element' is simgle DOM node.
});
});
}); {%endhighlight%}