JavaScriptでセレクタ/idにエスケープが必要な場面とやり方

JavaScriptで今まで気になってたことです。

要素の id / class などのセレクタのエスケープ

僕自身も理解をしていなかったので、
どうしてか動かずに困惑する場面もあります。

そこでJavaScriptのセレクタのエスケープ方法
この具体的な方法とコード例なんかをまとめました。

要素のid・クラスにはどんな文字でも使えるが…

初めにHTML上でのid/classの制限について

実は使用可能文字に制限はありません。

▼ こんな要素も普通に作れる

要素のid・classの値は数字から始められるし、なんなら日本語とか使っても問題ありません。構文上はどんな文字でも使えるんですよね。

違和感があるけどなんの問題もないです。

ただし「HTML上では」という条件がつきます。

数字から始まるセレクタはJSから参照できない

ところがJavaScript上ではセレクタに制限があります。

  • セレクタの先頭は数字から始められない
  • セレクタに特殊文字は含められない
  • もし使いたいならエスケープが必要

すこし具体的な例で考えてみます。

例えばこんな要素を定義したとしましょう。

▼ 数字から始まるクラスを含む要素

▼ これをJavaScriptコードから参照

▼ DOMExceptionエラーが発生!

※ 数字から始まるIDでも同様

アイテムを表示するとき、要素にそのIDを紐づけたいみたいな場面。HTML上では問題ないけど、JSコードからそのままセレクタできません。

だからエスケープという工夫が必要です。

セレクタはCSS.escape()でエスケープできる

便利なメソッドが用意されてます。

その名も CSS.escape() というメソッド

名前の通り、セレクタをエスケープできます。

▼ CSS.escape() - Web APIs | MDN

The CSS.escape() static method returns a string containing the escaped string passed as parameter, mostly for use as part of a CSS selector.

引用元 : https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

セレクタ文字列を渡すことにより、エスケープが必要な文字(数字・特殊文字・記号)をバックスラッシュ(\)でエスケープしてくれます。

以下はエスケープの例です。

  • user.name ⇒ user\.name
  • ()[]{} ⇒ \(\)\[\]\{\}
  • 1234567890 ⇒ \31 234567890

記号とかは前にバックスラッシュが付くだけ

混乱するのは数字の場合ですね。

数字のエスケープでは \31 のようにASCIIコードとしてエスケープします。例えば '1' のasciiコードは16進数で0x30になるので \31 という表現になるわけです。

数字の場合はこのルールが適用されます。

具体的なCSS.escape()の使用コード例

ということで具体的に使ってみます。

▼ このような要素があるとする

▼ セレクタをエスケープして要素取得

今度はDOMExceptionなく正常に取得できました。

ブラウザごとのCSS.escape()の対応状況

少し気になるのがブラウザの対応状況です。

▼ 詳しくは Can i use... をチェック

現時点で95%をカバーしてるので問題ないですね。

ただし例のごとくIEは対応してません、

以上、JavaScriptでセレクタのエスケープでした。ではまた

CSSではセレクタを \ でエスケープ可能

ちなみにCSSでのセレクタエスケープについて。

同様にバックスラッシュでエスケープ可能です。

▼ こんな感じでエスケープできる

規則は CSS.escape() と全く同じです。

ただ記述が特殊すぎて使うことは少なそう。