Discuss and resolve questions on Liquid, JavaScript, themes, sales channels, and site speed enhancements.
Hey there! I have recently built a small function using javascript that hides/shows product variants and was curious if the way I am doing is correct, or if there might be a more optimal way to do such a thing. For some additional context, I am using the IMPACT theme built by Maestrooo.
It seemed that the easiest route to go down is to load product data via json using a script file and parse that data to do any further actions. I thought about trying to use AJAX API to live load the data, but the script route was much more appealing. There are also some other functions, such as one that looks through all of the product thumbnails to hide/show them. Another one that on load only shows the currently selected variant.
Regardless, I would love some feedback and or constructive criticism as I would like to continue improving my code.
// js/sections/variant-picker.js
document.addEventListener("DOMContentLoaded", function () {
// Parse product data
const productDataScript = document.querySelector("script[data-product]");
if (!productDataScript) return;
let productData;
try {
productData = JSON.parse(productDataScript.textContent);
} catch (e) {
console.error("Failed to parse product data:", e);
return;
}
// Parse currently selected variant
const variantPicker = document.querySelector("variant-picker");
if (!variantPicker) return;
const selectedVariant = JSON.parse(variantPicker.querySelector("script[data-variant]")?.textContent || "{}");
const selectedID = selectedVariant?.featured_media?.id;
// Gather variants and their media IDs as a Set
const variantMediaIDs = new Set(
productData
.filter((variant) => variant.featured_media)
.map((variant) => variant.featured_media.id)
);
// Group images by their associated variant ID
const galleryImages = Array.from(document.querySelectorAll(".product-gallery__thumbnail"));
const groupedImages = new Map();
let currentVariantID = null;
galleryImages.forEach((image) => {
const imageMediaID = parseInt(image.id);
if (variantMediaIDs.has(imageMediaID)) {
currentVariantID = imageMediaID;
if (!groupedImages.has(currentVariantID)) {
groupedImages.set(currentVariantID, []);
}
}
if (currentVariantID) {
groupedImages.get(currentVariantID).push(image);
}
});
// Show images for the selected variant
function showImagesForVariant(selectedID) {
galleryImages.forEach((image) => {
const belongsToSelectedVariant = groupedImages.get(selectedID)?.includes(image);
image.classList.toggle("hidden", !belongsToSelectedVariant);
});
}
// Initial display for the currently selected variant
if (selectedID) showImagesForVariant(selectedID);
// Listen for variant changes and update the display
document.addEventListener("variant:change", function (event) {
const newSelectedVariant = event.detail.variant;
const newSelectedID = newSelectedVariant?.featured_media?.id;
if (newSelectedID) showImagesForVariant(newSelectedID);
});
});
Learn how to build powerful custom workflows in Shopify Flow with expert guidance from ...
By Jacqui May 7, 2025Did You Know? May is named after Maia, the Roman goddess of growth and flourishing! ...
By JasonH May 2, 2025Discover opportunities to improve SEO with new guidance available from Shopify’s growth...
By Jacqui May 1, 2025