実現したいこと
HTMLのbuttonをクリックしたときに、そのbuttonの傍にpopover属性を指定した要素を表示させたい。
表示/非表示はjavascriptで制御する。
[5/16 17:33 追記]
javascriptで制御したい理由は、buttonをクリックされたら実行されるjavascriptの処理結果に応じてpopoverを表示するかしないかを変えたい、あるいは表示内容を変更したいからです。
発生している問題・分からないこと
Javascriptを使用せずに自動的に表示させる場合には、buttonの傍に表示されます。
JavascriptのshowPopover()で表示されると離れた位置に表示されてしまいます。
popup位置の基準となる要素を何らかの方法で指定する必要があるのかがわかりません。
htmlの属性またはcssの記述が不足しているのでしょうか?
該当のソースコード
html
1<div style="position: relative;"> 2 3 <div id="pop1" style="margin:0; inset:0; position-area:top;" popover > 4 <div>あいうえお<br />かきく</div> 5 </div> 6 7 <button id="btnOK" style="margin:100px;" popovertarget="pop1"> 8 <span>意図した通りの要素の上になる</span> 9 </button> 10 11 <button id="btnFail" style="margin:100px;"> 12 <span>画面下になってしまう</span> 13 </button> 14 15 <script> 16 document.querySelector("#btnFail").addEventListener("click", (ev) => { 17 document.querySelector("#pop1").hidePopover(); 18 document.querySelector("#pop1").showPopover(); 19 }); 20 </script> 21</div>
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
Popover anchor positioningで説明されているposition-areaを使用してるがjavascriptからは効果がない。
javascriptでの場合に対象とする要素が指定できていないのではと考えていますが、開発者ツールでみても違いが見つけられません。
補足
chrome 136
edge 136
(firefoxではまったく位置が合わない、safariでは試せていないが、今回の質問ではchromium系のみでよい)
得られた回答を参考に実現できたコード
[5/16 17:53 追記]
クリックされた(スクリプト処理後の)時点での対象のpopovertarget
属性で判定されるようなので、非同期のawaitしてしまうと成功しませんでしたが、属性を書き換えてからclick()を呼び出すことで遅延させることができました。
html
1 document.querySelector("#btnFail").addEventListener("click", async (ev) => { 2 3 const btn = ev.currentTarget; 4 5 if (btn.hasAttribute("popovertarget")) { 6 return; 7 } 8 9 btn.innerText = "処理中"; 10 const result = await new Promise((r) => setTimeout(r, 1000, (Math.random() < 0.5))); 11 btn.innerText = result ? "合格" : "不合格"; 12 if (result) { 13 btn.setAttribute("popovertarget", "pop1"); 14 } 15 else { 16 btn.setAttribute("popovertarget", "pop2"); 17 } 18 19 btn.click(); 20 btn.removeAttribute("popovertarget"); 21 });
得られた回答を参考に実現できたコード 2
[5/16 18:20 追記]
HTMLとCSSでの関連は、styleにposition-anchor
とposition-name
の値が一致する組み合わせをつければ良さそうなので、HTMLで書くと以下のように。
html
1<div id="pop1" 2 style="position-anchor: --testAnchor; margin:0; inset:0; position-area:top; background-color: green; color: white;" 3 popover> 4 <div>合格</div> 5</div> 6<button id="btnFail" style="anchor-name:--testAnchor; margin:100px;"> 7 <span>2</span> 8</button>
これをjavascriptで実現すると
javascript
1document.querySelector("#btnFail").addEventListener("click", async (ev) => { 2 3 const btn = ev.currentTarget; 4 btn.innerText = "処理中"; 5 6 const result = await new Promise((r) => setTimeout(r, 1000, (Math.random() < 0.5))); 7 const pop = document.querySelector(result ? "#pop1" : "#pop2"); 8 9 const anchorName = "--testAnchor" + Date.now().toString(); 10 btn.style.anchorName = anchorName; 11 pop.style.positionAnchor = anchorName; 12 pop.showPopover(); 13});
とすることでshowPopover()でも任意に指定したボタンの傍に表示させることができるようになりました。
得られた回答を参考に実現できたコード 3
[5/16 18:55 追記]
showPopoverの引数で指定できる!!!
javascript
1document.querySelector("#btnFail").addEventListener("click", async (ev) => { 2 3 const btn = ev.currentTarget; 4 btn.innerText = "処理中"; 5 6 const result = await new Promise((r) => setTimeout(r, 1000, (Math.random() < 0.5))); 7 const pop = document.querySelector(result ? "#pop1" : "#pop2"); 8 pop.showPopover({ source: btn }); 9});

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/05/16 09:18
2025/05/16 09:37 編集
2025/05/16 09:36
2025/05/16 09:51
2025/05/16 09:59
2025/05/16 10:08