I'm trying to trigger custom event whenever Magento displays the product swatches in category view.
It looks like Magento uses ajax to load these swatches, they are not displayed on page load, they "pop" after a few moments. I need to add some custom JavaScript code after these swatches are actually displayed. So I thought the best way will be to trigger custom event just after Magento finishes to render the swatches. But I'm not sure how to do this correctly in Magento 2.
What I want to do is to trigger a custom event $(document).trigger('swatches-visible'); when a block of swatches is finally displayed on the page.
And then, an event handler will execute a function:
$(document).on('swatches-visible', function() {
doSomething();
});
That function doSomething() is already added via RequireJS in one of the template files:
<script type="text/javascript">
requirejs(['jquery'], function(jQuery) {
function doSomething()
{
// Here make some layout changes of the products list...
}
});
</script>
3 Answers 3
I used the event 'swatch.initialized' to fire a function after swatches are loaded in the product page:
$(document).on('swatch.initialized', function() {
// do something
})
The event is triggered in Magento_Swatches/js/swatch-renderer.js
$(this.element).trigger('swatch.initialized');
Try With This one.
<script type="text/javascript">
require(['jquery','Magento_Swatches/js/swatch-renderer'],function(,ドルswatch){
$(document).on('swatch.initialized', function() {
function doSomething()
{
// Here make some layout changes of the products list...
}
});
</script>
While @Guillem Lorman's answer is good. A more general approach, which gives you more control, is to use mixins. This allows you to trigger your script before/after a certain function has completed. Like this:
app/code/Namespace/ModuleName/view/frontend/requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Swatches/js/swatch-renderer': {
'Namespace_ModuleName/js/swatch-renderer-mixin': true
}
}
}
};
Then go through the code of swatch-renderer.js to see before/after which function you'd like to trigger your code. E.g. to plug into _RenderSwatchSelect you could do the following:
app/code/Namespace/ModuleName/viewfrontend/web/js/swatch-renderer-mixin.js
define([
'jquery'
], function (
$
) {
'use strict';
return function (widget) {
$.widget('mage.SwatchRenderer', widget, {
// Pay attention to parameters in the original function.
_RenderSwatchSelect: function(config, chooseText) {
// Trigger original function.
this._super(config, chooseText);
console.log('Yeah!');
/**
* If you want to trigger your function before the original function,
* you'd place this.super(config, chooseText) here.
*/
},
});
return $.mage.SwatchRenderer;
}
});
-
Exactly something that I was looking for. gives much more access than just initialise event. ThanksShahzaib Sheikh– Shahzaib Sheikh2020年09月25日 11:28:01 +00:00Commented Sep 25, 2020 at 11:28
Explore related questions
See similar questions with these tags.
$(document).trigger('swatches-visible')when a block of swatches is finally displayed. And then, an event handler will execute a function:$(document).on('swatches-visible', function(e) { doSomething(); });That functiondoSomething()is already added via RequireJS in one of the template files. What you proposed sounds like a good solution but I'm not sure how to use it in my case. Isn'tdata-mage-initexecuted only on page load? Note that the blocks of swatches for all products, e.g.<div class="swatch-opt-1822">...</div>, are displayed with a delay, not instantly on page load.data-mage-initis,x-magento-initis different although I'm not sure if that is also only on page load (the dev docs don't mention). If it is page load then the only other method I can think of is to initialise the JS inside the swatch template. Require works in templates to so I don't see why that wouldn't work.