From 84f20323da291b5d2bb39a939ac66b648708ae56 Mon Sep 17 00:00:00 2001 From: Tony Date: Sun, 11 Feb 2024 11:30:01 +0100 Subject: [PATCH 1/2] remove jquery dependency --- .../catalog/media/js.phtml | 17 +- .../js/configurableswatches/product-media.js | 145 ++++++++++++------ .../js/configurableswatches/swatches-list.js | 50 +++--- 3 files changed, 138 insertions(+), 74 deletions(-) diff --git a/app/design/frontend/rwd/default/template/configurableswatches/catalog/media/js.phtml b/app/design/frontend/rwd/default/template/configurableswatches/catalog/media/js.phtml index 5a4063be4f9..afb906fdcdb 100644 --- a/app/design/frontend/rwd/default/template/configurableswatches/catalog/media/js.phtml +++ b/app/design/frontend/rwd/default/template/configurableswatches/catalog/media/js.phtml @@ -18,11 +18,20 @@ ?> diff --git a/skin/frontend/rwd/default/js/configurableswatches/product-media.js b/skin/frontend/rwd/default/js/configurableswatches/product-media.js index 25026074825..7e8afe736a6 100644 --- a/skin/frontend/rwd/default/js/configurableswatches/product-media.js +++ b/skin/frontend/rwd/default/js/configurableswatches/product-media.js @@ -80,18 +80,25 @@ var ConfigurableMediaImages = { } //second, get any product which is compatible with currently selected option(s) - $j.each(fallback['option_labels'], function(key, value) { - var image = value['configurable_product'][ConfigurableMediaImages.imageType]; - var products = value['products']; - - if(image) { //configurable product has image in the first place - //if intersection between compatible products and this label's products, we found a match - var isCompatibleProduct = ConfigurableMediaImages.arrayIntersect(products, compatibleProducts).length > 0; - if(isCompatibleProduct) { - return image; + var optionLabels = fallback['option_labels']; + for (var key in optionLabels) { + if (optionLabels.hasOwnProperty(key)) { + var value = optionLabels[key]; + var image = value['configurable_product'][ConfigurableMediaImages.imageType]; + var products = value['products']; + + if (image) { //configurable product has image in the first place + //if intersection between compatible products and this label's products, we found a match + var isCompatibleProduct = products.filter(function(productId) { + return compatibleProducts.includes(productId); + }).length > 0; + + if (isCompatibleProduct) { + return image; + } } } - }); + } //third, get image off of child product which is compatible var childSwatchImage = null; @@ -118,74 +125,122 @@ var ConfigurableMediaImages = { getImageObject: function(productId, imageUrl) { var key = productId+'-'+imageUrl; if(!ConfigurableMediaImages.imageObjects[key]) { - var image = $j(''); - image.attr('src', imageUrl); + var image = document.createElement('img'); + image.src = imageUrl; ConfigurableMediaImages.imageObjects[key] = image; } return ConfigurableMediaImages.imageObjects[key]; }, - updateImage: function(el) { - var select = $j(el); - var label = select.find('option:selected').attr('data-label'); + updateImage(el) { + var select = el; + var label = select.options[select.selectedIndex].getAttribute('data-label'); var productId = optionsPrice.productId; //get product ID from options price object //find all selected labels - var selectedLabels = new Array(); + var selectedLabels = []; - $j('.product-options .super-attribute-select').each(function() { - var $option = $j(this); - if($option.val() != '') { - selectedLabels.push($option.find('option:selected').attr('data-label')); + var superAttributeSelects = document.querySelectorAll('.product-options .super-attribute-select'); + superAttributeSelects.forEach(function(option) { + if (option.value !== '') { + selectedLabels.push(option.options[option.selectedIndex].getAttribute('data-label')); } }); var swatchImageUrl = ConfigurableMediaImages.getSwatchImage(productId, label, selectedLabels); - if(!ConfigurableMediaImages.isValidImage(swatchImageUrl)) { + if (!ConfigurableMediaImages.isValidImage(swatchImageUrl)) { + console.log('no image found'); return; } var swatchImage = ConfigurableMediaImages.getImageObject(productId, swatchImageUrl); - ProductMediaManager.swapImage(swatchImage); + this.swapImage(swatchImage); + }, + + swapImage: function(targetImage) { + targetImage.classList.add('gallery-image'); + + var imageGallery = document.querySelector('.product-image-gallery'); + + if (targetImage.complete) { // image already loaded -- swap immediately + var galleryImages = imageGallery.querySelectorAll('.gallery-image'); + galleryImages.forEach(function(image) { + image.classList.remove('visible'); + }); + + // move target image to correct place, in case it's necessary + imageGallery.appendChild(targetImage); + + // reveal new image + targetImage.classList.add('visible'); + } else { // need to wait for image to load + // add spinner + imageGallery.classList.add('loading'); + + // move target image to correct place, in case it's necessary + imageGallery.appendChild(targetImage); + + // wait until image is loaded + targetImage.addEventListener('load', function() { + // remove spinner + imageGallery.classList.remove('loading'); + + // hide old image + var galleryImages = imageGallery.querySelectorAll('.gallery-image'); + galleryImages.forEach(function(image) { + image.classList.remove('visible'); + }); + + // reveal new image + targetImage.classList.add('visible'); + }); + } }, wireOptions: function() { - $j('.product-options .super-attribute-select').change(function(e) { - ConfigurableMediaImages.updateImage(this); + var selectElements = document.querySelectorAll('.product-options .super-attribute-select'); + selectElements.forEach(function(selectElement) { + selectElement.addEventListener('change', function(e) { + ConfigurableMediaImages.updateImage(this); + }); }); }, swapListImage: function(productId, imageObject) { - var originalImage = $j('#product-collection-image-' + productId); + var originalImage = document.querySelector('#product-collection-image-' + productId); - if(imageObject[0].complete) { //swap image immediately + if (imageObject.complete) { // swap image immediately - //remove old image - originalImage.addClass('hidden'); - $j('.product-collection-image-' + productId).remove(); + // remove old image + originalImage.classList.add('hidden'); + document.querySelectorAll('.product-collection-image-' + productId).forEach(function (image) { + image.remove(); + }); - //add new image - imageObject.insertAfter(originalImage); + // add new image + originalImage.parentNode.insertBefore(imageObject, originalImage.nextSibling); - } else { //need to load image + } else { // need to load image - var wrapper = originalImage.parent(); + var wrapper = originalImage.parentNode; - //add spinner - wrapper.addClass('loading'); + // add spinner + wrapper.classList.add('loading'); - //wait until image is loaded - imagesLoaded(imageObject, function() { - //remove spinner - wrapper.removeClass('loading'); + // wait until image is loaded + imageObject.addEventListener('load', function () { + // remove spinner + wrapper.classList.remove('loading'); - //remove old image - originalImage.addClass('hidden'); - $j('.product-collection-image-' + productId).remove(); + // remove old image + originalImage.classList.add('hidden'); + document.querySelectorAll('.product-collection-image-' + productId).forEach(function (image) { + image.remove(); + }); - //add new image - imageObject.insertAfter(originalImage); + // add new image + originalImage.parentNode.insertBefore(imageObject, originalImage.nextSibling); }); } @@ -198,7 +253,7 @@ var ConfigurableMediaImages = { } var newImage = ConfigurableMediaImages.getImageObject(productId, swatchImageUrl); - newImage.addClass('product-collection-image-' + productId); + newImage.classList.add('product-collection-image-' + productId); ConfigurableMediaImages.swapListImage(productId, newImage); }, diff --git a/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js b/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js index 4a769494d7d..91ab65b3dd6 100644 --- a/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js +++ b/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js @@ -15,63 +15,63 @@ var ConfigurableSwatchesList = { swatchesByProduct: {}, - init: function() - { + init: function() { var that = this; - $j('.configurable-swatch-list li').each(function() { - that.initSwatch(this); - var $swatch = $j(this); - if ($swatch.hasClass('filter-match')) { - that.handleSwatchSelect($swatch); + document.querySelectorAll('.configurable-swatch-list li').forEach(function(element) { + that.initSwatch(element); + var swatch = element; + if (swatch.classList.contains('filter-match')) { + that.handleSwatchSelect(swatch); } }); }, - initSwatch: function(swatch) + initSwatch: function initSwatch(swatch) { var that = this; - var $swatch = $j(swatch); + var $swatch = swatch; var productId; - $j($swatch).hover(function() { + $swatch.addEventListener('mouseenter', function() { /** * * - Preview the stock status **/ - var swatchUl = $swatch.parent(); - swatchUl.find('.x').each(function(){ - $j(this).show(); - $j(this).closest('li').addClass('not-available'); + var swatchUl = $swatch.parentNode; + var xElements = swatchUl.querySelectorAll('.x'); + xElements.forEach(function(element) { + element.style.display = 'block'; + element.closest('li').classList.add('not-available'); }); }); - if (productId = $swatch.data('product-id')) { - if (typeof(this.swatchesByProduct[productId]) == 'undefined') { + if (productId = $swatch.dataset.productId) { + if (typeof this.swatchesByProduct[productId] == 'undefined') { this.swatchesByProduct[productId] = []; } this.swatchesByProduct[productId].push($swatch); - $swatch.find('a').on('click', function(e) { + var anchorElement = $swatch.querySelector('a'); + anchorElement.addEventListener('click', function(e) { e.preventDefault(); that.handleSwatchSelect($swatch); }); } }, - handleSwatchSelect: function($swatch) - { - var productId = $swatch.data('product-id'); + handleSwatchSelect: function(swatch) { + var productId = swatch.dataset.productId; var label; - if (label = $swatch.data('option-label')) { + if (label = swatch.dataset.optionLabel) { ConfigurableMediaImages.swapListImageByOption(productId, label); } - $j.each(this.swatchesByProduct[productId], function(key, $productSwatch) { - $productSwatch.removeClass('selected'); + Array.from(this.swatchesByProduct[productId]).forEach(function(productSwatch) { + productSwatch.classList.remove('selected'); }); - $swatch.addClass('selected'); + swatch.classList.add('selected'); } }; -$j(document).on('configurable-media-images-init', function(){ +document.addEventListener('DOMContentLoaded', function() { ConfigurableSwatchesList.init(); }); From 3292a8893c574d464b15f16f7e14dc8988eb9f0c Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 22 Feb 2024 08:58:27 +0100 Subject: [PATCH 2/2] update swatches-list.js --- .../rwd/default/js/configurableswatches/swatches-list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js b/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js index 91ab65b3dd6..7613bd075d5 100644 --- a/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js +++ b/skin/frontend/rwd/default/js/configurableswatches/swatches-list.js @@ -26,7 +26,7 @@ var ConfigurableSwatchesList = { }); }, - initSwatch: function initSwatch(swatch) + initSwatch: function(swatch) { var that = this; var $swatch = swatch;