質問です
とりあえずソースコードは次のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>WebContent Sample</title> </head> <body> <!-- (参考) https://developers.google.com/web/fundamentals/web-components/shadowdom?hl=ja https://html5experts.jp/shumpei-shiraishi/24239/ --> <script> class QuestionBox extends HTMLElement { //********************************************************************* // Static Methods //********************************************************************* static get template(){ return ` <div id="question-str" class="question-cell"> <slot></slot> </div> <div class="question-cell"> <input type="radio" name="rd-question" value="0"> <input type="radio" name="rd-question" value="1"> <input type="radio" name="rd-question" value="2"> <input type="radio" name="rd-question" value="3"> <input type="radio" name="rd-question" value="4"> </div> <style> .question-cell { display: table-cell; } </style> `; } //********************************************************************* // Member Methods //********************************************************************* constructor(){ super(); } connectedCallback(){ let sr = this.attachShadow({mode: "open"}); sr.innerHTML = QuestionBox.template; this.style.display = "table-row"; this.defaultCheck(); } defaultCheck(){ let ipts = this.shadowRoot.querySelectorAll("input"); let val = this.getAttribute("value"); ipts[val].checked = true; } get value(){ const ipts = this.shadowRoot.querySelectorAll("input"); for(let i=0; i<ipts.length; i++){ if(ipts[i].checked){ return parseInt(ipts[i].value); } } } set value(val){ let ipts = this.shadowRoot.querySelectorAll("input"); this.setAttribute("value", val); for(let i=0; i<ipts.length; i++){ if(parseInt(ipts[i].value) == val){ ipts[i].checked = true; } } } } customElements.define('question-box', QuestionBox); </script> <div style="display: table;"> <question-box value="2"><p>質問1です</p></question-box> <question-box value="0"><p>質問2です</p></question-box> </div> <script> var qs = document.getElementsByTagName("question-box"); for(var i=0; i<qs.length; i++){ console.log(qs[i].value); qs[i].value += 1; } </script> </body> </html>
このカスタムタグを作るためのクラスです。
template()、constructor()、connectedCallback()などは前のサンプルと同じことなので説明しません。
属性valueのgetter/setterとシャドウルート以下の要素との連動の説明が主眼です。
「get value()」がgetterです。
これはこのカスタムタグのvalueプロパティを参照した時に取得できる値として機能します。
実際にはカスタムタグ内の<input>のうちcheckedになっているもののvalueを取得します。
this.shadowRoot.querySelectorAll("input")でシャドウルート以下の<input>を取得します。
なお、シャドウルート以下の要素の対してはelement.getElementsByTagName()やelement.getElementsByClassName()は機能しないのでquerySelectorAll()を使用します。
querySelector()とgetElementById()は機能します。
あとは普通にcheckedの<input>を探し、そのvalueを返すだけです。
「set value()」がgetterです。
querySelectorAll()を使っているのはgetterで説明した通りです。
あとは普通にsetterの引数valと一致するvalueを持つ<input>をcheckedにするだけです。
これだけでJSで操作するときのプロパティはもちろん、HTMLから値を設定するときのvalue属性も有効になります。
下がサンプルで、1つめはvalue=2、2つめはvalue=0を属性として指定しています。
質問1です
質問2です
87〜93行目のコードは動作確認です。
console.log()で値が取得できることを確認し、そのあと+1してプロパティの変更が有効なことを確認しています。
実際には次の様になります。
質問1です
質問2です
値の取得はコンソールをみないとダメですが、選択しているラジオボタンが+1されているのが確認できます。