When the breakpoint is single everything works fine, when I try to add one more breakpoint, it doesn't work. Here is my code from view.xml. So firstly I need to display nav as vertical thumbs, next break as horizontal and last as dots.
3 Answers
Try this Solution working fine for me change code in XML file your-theme/etc/view.xml
<var name="breakpoints">
<var name="mobile">
<var name="conditions">
<var name="max-width">767px</var>
</var>
<var name="options">
<var name="options">
<var name="nav">dots</var>
</var>
</var>
</var>
<var name="tablet">
<var name="conditions">
<var name="min-width">768px</var>
<var name="max-width">900px</var>
</var>
<var name="options">
<var name="options">
<var name="navdir">horizontal</var>
</var>
</var>
</var>
and also change the line in your-theme/web/mage/gallery/gallery.js
settings.api.updateOptions(settings.defaultConfig.options, true);
to
if(window.innerWidth > 767) {
settings.api.updateOptions(settings.defaultConfig.options, true);
}
Indeed it's still not working with multiple breakpoints in 2.4. I debugged gallery.js and how it works is :
There is a listener called every time the browser is resized and a check is done for every breakpoint you declared. For each breakpoint, in gallery.js, there is an "entry" and "exit" function. The entry function will apply the options of the breakpoint. The exit function will reset to default config the gallery.
The problem, in the example of 2 breakpoints, on resizing it will do :
- exit breakpoint 1 called
- entry breakpoint 2 called
OR
- entry breakpoint 1 called
- exit breakpoint 2 called
Sadly, in the second case, exit reset your parameters... I made it work remplacing :
settings.api.updateOptions(settings.breakpoints[pair[0]].options, true);
by
setTimeout(function () {
settings.api.updateOptions(settings.breakpoints[pair[0]].options, true);
}, 300);
Another better workaround (I guess) would be to add a return directly in the exit function, but then you have to declare all breakpoints. Indeed if you exit a breakpoint, it won't reset to default value.
It's obviously a workaround and Magento should fix this issue...
-
You are right - MAgento should fix it ;). I even fixed it for Magento and it was merged in September... It is in 2.4-develop so I guess it will be in 2.4.2 version Commented Dec 16, 2020 at 1:52
Here is my fix merged into latest Magento 2.4-develop version: https://github.com/magento/magento2/pull/29934/files
You can try to implement this mixin:
gallery-mixin.js:
define([
'jquery',
'underscore',
'matchMedia',
], function ($, _, mediaCheck) {
'use strict';
return function (targetModule) {
return targetModule.extend({
/**
* Creates breakpoints for gallery.
*/
setupBreakpoints: function () {
var pairs,
settings = this.settings,
config = this.config,
startConfig = this.startConfig,
isTouchEnabled = this.isTouchEnabled;
if (_.isObject(settings.breakpoints)) {
pairs = _.pairs(settings.breakpoints);
var isInitialized = {};
_.each(pairs, function (pair) {
var mediaQuery = pair[0];
isInitialized[mediaQuery] = false;
mediaCheck({
media: mediaQuery,
/**
* Is triggered when breakpoint enties.
*/
entry: function () {
$.extend(true, config, _.clone(startConfig));
settings.api.updateOptions(settings.defaultConfig.options, true);
if (settings.isFullscreen) {
settings.api.updateOptions(settings.fullscreenConfig, true);
}
if (isTouchEnabled) {
settings.breakpoints[mediaQuery].options.arrows = false;
if (settings.breakpoints[mediaQuery].options.fullscreen) {
settings.breakpoints[mediaQuery].options.fullscreen.arrows = false;
}
}
settings.api.updateOptions(settings.breakpoints[mediaQuery].options, true);
$.extend(true, config, settings.breakpoints[mediaQuery]);
settings.activeBreakpoint = settings.breakpoints[mediaQuery];
isInitialized[mediaQuery] = true;
},
/**
* Is triggered when breakpoint exits.
*/
exit: function () {
if (isInitialized[mediaQuery]) {
$.extend(true, config, _.clone(startConfig));
settings.api.updateOptions(settings.defaultConfig.options, true);
if (settings.isFullscreen) {
settings.api.updateOptions(settings.fullscreenConfig, true);
}
settings.activeBreakpoint = {};
}
else {
isInitialized[mediaQuery] = true;
}
}
});
});
}
}
});
};
});
requirejs-config.js (ex. yourtheme/Magento_Theme/requirejs-config.js)
var config = {
config: {
mixins: {
"mage/gallery/gallery": {
"Magento_Theme/js/mixins/gallery-mixin": true
},
}
},
};