質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%

Q&A

解決済

2回答

738閲覧

javascript class内のメソッドの使用方法

cheche0830

総合スコア187

0グッド

0クリップ

投稿2022/11/30 23:33

編集2022/12/01 01:13

前提

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}&section_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など通らずでした。。

ご教授お願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

int32_t

2022/12/01 00:08 編集

HTMTLも開示してください。とくに、<variant-selects> と id=variant_choose の関係が不明です。
guest

回答2

0

<variant-selects>がid=variant_chooseであるなら

javascript

1this.onVariantChange();

で呼び出せます。
もともとchangeで呼び出す処理ですからカスタムイベントでもよいかも

javascript

1<script> 2class VariantSelects extends HTMLElement { 3 constructor() { 4 super(); 5 this.addEventListener('change', this.onVariantChange); 6 } 7 onVariantChange() { 8 console.log([event.target,event.type]); 9 } 10} 11customElements.define('variant-selects', VariantSelects); 12window.addEventListener('DOMContentLoaded', ()=>{ 13 document.getElementById("variant_choose").addEventListener('click',function(){ 14 this.onVariantChange(); 15 const ce = new CustomEvent("HTMLEvents"); 16 ce.initEvent('change', true, true ); 17 this.dispatchEvent(ce); 18 }); 19}); 20</script> 21<variant-selects id="variant_choose">click here!</variant-selects>

命題がわかりづらくselectのchangeをトリガーに<variant-selects>のchangeイベントを発生させるとも読めます。どうしたいか明示していただいたほうがよいかも。

投稿2022/12/01 01:17

yambejp

総合スコア114843

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cheche0830

2022/12/01 01:33

ありがとうございます!こちらも後ほど試してみます!
guest

0

ベストアンサー

VariantSelects のメソッドを呼ぶには、VariantSelects のインスタンス(HTMLの要素)を入手する必要があります。querySelector() などで入手しましょう。

js

1let trigger = document.getElementById("variant_choose"); 2trigger.addEventListener('click', function() { 3 document.querySelector('variant-selects').onVariantChange(); 4});

投稿2022/12/01 01:26

int32_t

総合スコア20884

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cheche0830

2022/12/01 01:33

出来ました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問