-
-
Save patrickbolle/95539fbe2a691efa5b59da645fb3dbbb to your computer and use it in GitHub Desktop.
Shopify JS Variant Listener
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This class contains general helper methods. | |
*/ | |
class Helper { | |
/** | |
* @param {String} name | |
* @returns {String|null} | |
*/ | |
static getQueryParameter(name) { | |
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]') | |
const regex = new RegExp('[\\?&]' + name + '=([^&#]*)') | |
const results = regex.exec(location.search) | |
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')) | |
} | |
} | |
/** | |
* This class contains Shopify related helper methods. | |
*/ | |
class ShopifyHelper { | |
/** | |
* @returns {String|null} | |
*/ | |
static getSelectedVariantId() { | |
// Try to get variant id from form element with name id | |
const addToCartForm = document.querySelector('form[action^="/cart/add"]') | |
if (addToCartForm) { | |
const input = addToCartForm.querySelector('[name="id"]') | |
const submitButton = addToCartForm.querySelector('[type="submit"]') | |
// If the submit button is disabled, the input value is most likely wrong | |
// because it got autofilled on initial page load with the first available product variant id. | |
if ( | |
(!submitButton || submitButton.disabled !== true) && | |
input && | |
input.value | |
) { | |
return input.value | |
} | |
} | |
// Try to get variant id from "variant" query parameter. | |
const queryParameter = Helper.getQueryParameter('variant') | |
if (queryParameter) { | |
return queryParameter | |
} | |
// Try to get variant id from ShopifyAnalytics.meta object | |
if ( | |
self.ShopifyAnalytics && | |
self.ShopifyAnalytics.meta && | |
self.ShopifyAnalytics.meta.selectedVariantId | |
) { | |
return self.ShopifyAnalytics.meta.selectedVariantId | |
} | |
// No variant id found | |
return null | |
} | |
/** | |
* @returns {Array<Element>} | |
*/ | |
static getAddToCartFormElements() { | |
const foundElements = [] | |
const elementTypes = ['select', 'input'] | |
for (let elementType of elementTypes) { | |
let elements = document.querySelectorAll(`form[action^="/cart/add"] ${elementType}`) | |
for (let element of elements) { | |
foundElements.push(element) | |
} | |
} | |
return foundElements | |
} | |
/** | |
* @param {Function} eventHandler | |
*/ | |
static addVariantListeners(eventHandler) { | |
for (let element of ShopifyHelper.getAddToCartFormElements()) { | |
element.addEventListener('change', eventHandler) | |
} | |
} | |
/** | |
* @param {Function} eventHandler | |
*/ | |
static removeVariantListeners(eventHandler) { | |
for (let element of ShopifyHelper.getAddToCartFormElements()) { | |
element.removeEventListener('change', eventHandler) | |
} | |
} | |
} | |
const initApp = () => { | |
let selectedVariantId = ShopifyHelper.getSelectedVariantId() | |
console.log('selected variant id is', selectedVariantId) | |
const variantHandler = (event) => { | |
const variantId = ShopifyHelper.getSelectedVariantId() | |
if (selectedVariantId !== variantId) { | |
selectedVariantId = variantId | |
console.log('selected variant id changed to', selectedVariantId) | |
} | |
} | |
ShopifyHelper.addVariantListeners(variantHandler) | |
} | |
if (document.readyState !== 'loading') { | |
setTimeout(initApp, 0) | |
} else { | |
document.addEventListener('DOMContentLoaded', initApp) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment