前提
javascriptのClassで書かれている中のメソッドを利用したい
※もっと細かく言いますと、現在、selectでオプションを変更すると下記のclassが走り、カートへ追加ボタンを押すと該当の商品がカートへ入るようになっているのですが、その選択肢を別ページからあらかじめ受け取って選択しておいた状態にしたいのですが、(そこまではできています)changeイベントが走っていないので、カートへ追加されません。なので、selectをchangeさせずに、もしくはchnageさせたことにして、進めたいというのが本筋です。下記のアイデアはカートへ追加するボタンを押したときにchangeイベントを無理やり動かせばいいのではないかというものです。
実現したいこと
document.getElementById("variant_choose");にそのメソッドイベントを付与したい。
発生している問題・エラーメッセージ
Uncaught TypeError: Cannot read properties of undefined (reading 'onVariantChange')
該当のソースコード
//html //現在こちらのselectを変更した時のみeventが発生 <variant-selects class="no-js-hidden" data-section="template--16558929641692__main" data-url="/products/5pack"><div class="product-form__input product-form__input--dropdown"> <label class="form__label" for="Option-template--16558929641692__main-0"> 味 </label> <div class="select"> <select id="Option-template--16558929641692__main-0" class="select__select" name="options[味]" form="product-form-template--16558929641692__main"> <option value="aaa" selected="selected"> aaa </option> </select> </div> </div> </variant-selects> //こちらをクリックしたときにも同じものを発動させたい <button id="variant_choose">button</button> class VariantSelects extends HTMLElement { constructor() { super(); this.addEventListener('change', this.onVariantChange); } onVariantChange() { console.log("variant"); this.updateOptions(); this.updateMasterId(); this.toggleAddButton(true, '', false); this.updatePickupAvailability(); this.removeErrorMessage(); if (!this.currentVariant) { this.toggleAddButton(true, '', true); this.setUnavailable(); } else { this.updateMedia(); this.updateURL(); this.updateVariantInput(); this.renderProductInfo(); this.updateShareUrl(); } } updateOptions() { this.options = Array.from(this.querySelectorAll('select'), (select) => select.value); } updateMasterId() { this.currentVariant = this.getVariantData().find((variant) => { return !variant.options.map((option, index) => { return this.options[index] === option; }).includes(false); }); } updateMedia() { if (!this.currentVariant) return; if (!this.currentVariant.featured_media) return; const mediaGallery = document.getElementById(`MediaGallery-${this.dataset.section}`); mediaGallery.setActiveMedia(`${this.dataset.section}-${this.currentVariant.featured_media.id}`, true); const modalContent = document.querySelector(`#ProductModal-${this.dataset.section} .product-media-modal__content`); if (!modalContent) return; const newMediaModal = modalContent.querySelector( `[data-media-id="${this.currentVariant.featured_media.id}"]`); modalContent.prepend(newMediaModal); } updateURL() { if (!this.currentVariant || this.dataset.updateUrl === 'false') return; window.history.replaceState({ }, '', `${this.dataset.url}?variant=${this.currentVariant.id}`); } updateShareUrl() { const shareButton = document.getElementById(`Share-${this.dataset.section}`); if (!shareButton || !shareButton.updateUrl) return; shareButton.updateUrl(`${window.shopUrl}${this.dataset.url}?variant=${this.currentVariant.id}`); } updateVariantInput() { const productForms = document.querySelectorAll(`#product-form-${this.dataset.section}, #product-form-installment-${this.dataset.section}`); productForms.forEach((productForm) => { const input = productForm.querySelector('input[name="id"]'); input.value = this.currentVariant.id; input.dispatchEvent(new Event('change', { bubbles: true })); }); } updatePickupAvailability() { const pickUpAvailability = document.querySelector('pickup-availability'); if (!pickUpAvailability) return; if (this.currentVariant && this.currentVariant.available) { pickUpAvailability.fetchAvailability(this.currentVariant.id); } else { pickUpAvailability.removeAttribute('available'); pickUpAvailability.innerHTML = ''; } } removeErrorMessage() { const section = this.closest('section'); if (!section) return; const productForm = section.querySelector('product-form'); if (productForm) productForm.handleErrorMessage(); } renderProductInfo() { fetch(`${this.dataset.url}?variant=${this.currentVariant.id}§ion_id=${this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section}`) .then((response) => response.text()) .then((responseText) => { const html = new DOMParser().parseFromString(responseText, 'text/html') const destination = document.getElementById(`price-${this.dataset.section}`); const source = html.getElementById(`price-${this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section}`); if (source && destination) destination.innerHTML = source.innerHTML; const price = document.getElementById(`price-${this.dataset.section}`); if (price) price.classList.remove('visibility-hidden'); this.toggleAddButton(!this.currentVariant.available, window.variantStrings.soldOut); }); } toggleAddButton(disable = true, text, modifyClass = true) { const productForm = document.getElementById(`product-form-${this.dataset.section}`); if (!productForm) return; const addButton = productForm.querySelector('[name="add"]'); const addButtonText = productForm.querySelector('[name="add"] > span'); if (!addButton) return; if (disable) { addButton.setAttribute('disabled', 'disabled'); if (text) addButtonText.textContent = text; } else { addButton.removeAttribute('disabled'); addButtonText.textContent = window.variantStrings.addToCart; } if (!modifyClass) return; } setUnavailable() { const button = document.getElementById(`product-form-${this.dataset.section}`); const addButton = button.querySelector('[name="add"]'); const addButtonText = button.querySelector('[name="add"] > span'); const price = document.getElementById(`price-${this.dataset.section}`); if (!addButton) return; addButtonText.textContent = window.variantStrings.unavailable; if (price) price.classList.add('visibility-hidden'); } getVariantData() { this.variantData = this.variantData || JSON.parse(this.querySelector('[type="application/json"]').textContent); return this.variantData; } } customElements.define('variant-selects', VariantSelects); //ここで独自の要素にイベントを追加したい。 let trigger = document.getElementById("variant_choose"); trigger.addEventListener('click', function() { this.VariantSelects.onVariantChange(); });
試したこと
let trigger = document.getElementById("variant_choose"); trigger.addEventListener('click', function() { this.VariantSelects.onVariantChange();//× VariantSelects.onVariantChange();//× VariantSelects();//× });
いろいろ、書き方を試してみたのですが、どちらもnot a functionなど通らずでした。。
ご教授お願いいたします。
HTMTLも開示してください。とくに、<variant-selects> と id=variant_choose の関係が不明です。

回答2件
あなたの回答
tips
プレビュー