選択部分のHTMLタグを取得する

てら
2022-08-26
てら
2022-08-26

・ブログを作りたい

・Twitterみたいな小さな機能のコメントできる掲示板を気軽に作りたい!

などという場合に、大体はリッチテキストエディタなどを使うとおもいますが、
「デザインをもっと自由にしたい!」「多機能じゃなくていいんだけど!」みたいな場合に
「ContentEditable」という機能で少しだけHTMLで修飾できるエディタを利用することができます。

さて、このContentEditable、Caretの位置の取得などで工夫が必要なものでした。
Caretの記事はまたいつか元気な時に描くとして、今回は「マウスで選択した部分にタグが含まれているか?」という判断をしたい時に
結構詰まってしまったので書き残しておきます。

まずは選択部分の要素を取得しよう


大体「マウス選択 HTML 取得」とかで検索すると出てきます。
cloneContentsを使いましょう。

const doms = document.getSelection().getRangeAt(0).cloneContents()
const bolds = doms.querySelectorAll('b')



これで何だかBタグが含まれる場合は取得できそうです。

 

それではこれで試してみましょう



まずはこのパターン
bold_setting_1.png
bolds.lengthで確認するとになりました!含まれていると認識してくれましたね。

次は一部だけ含んでいるパターン。ちょっと心配ですね。
boldd_setting_2.png
bolds.length=1!!!ちゃんと一部含んでても認識してくれました。

次はこのパターン。
bold_setting_3.png
bolds.lengthは… 0!!!

絶対太字なのになんで太字じゃないんですか???????????????👁👁

理由はこういう風に↓
bold_setting_4.png

bold
  └text
        └太文字



選択している部分が<b>に囲まれているtextノードだから です!

ではこういうBoldの中のテキストノードを選択している時に検知するときはどうしたらいいのか?
対策としてはcontaintsNodeと組み合わせて使ったり…(使い方はこちらがわかりやすかったです)
https://lab.syncer.jp/Web/API_Interface/Reference/IDL/Selection/containsNode/


遠回りですがpreviousElementSiblingなど使ってみたり…
なんか他に絶対方法あるだろと思うんですが、選択要素の前後関係をみたりキャレットの位置をみたりしながら判断しました。
Nodeから見るときは色々なパターンで試してみる必要がありますね。