HTML の DOM に指定した id って JavaScript のグローバル変数に格納されるって知ってた?

2 min read読了の目安(約2200字

はじめに

タイトルの通りなんですが, HTML の DOM に指定した id はすべて同じ変数名としてグローバル変数に格納されます.

つまり id を好き勝手付けちゃうと知らぬ間にグローバル空間が汚染され, 予期せぬバグを起こしてしまう可能性があります. なので id の値は慎重に考えて付けましょうという.

っという注意喚起もしたいんですが, 実は今回伝えたいのはそれではありません.

メインはこの仕組みを逆手に取って活用することで手軽にツールを作ったりできますよーという紹介になります.

この tips を活用して, ちょっとした Markdown Editor も作ってみたのでよかったら参考にしてください.

具体例

具体的な例は以下です.
このように, 要素に id を指定していた場合はグローバルに変数として格納されているので document.getElementById を呼ばなくても参照できます.

<div id='hoge'>Hello, world!</div>
console.log(window.hoge.innerHTML); // Hello, world!

Markdown Editor(サンプルプログラム)

今回作った Markdown Editor です, 左側に Markdown を書くとリアルタイムで変換後の内容が右に表示されます.

https://runstant.com/phi/projects/7c568a34

コードは以下です.

index.html
<body>
  <main class='main'>
    <textarea id='$input'></textarea>
    <div id='$output'></div>
  </main>
  
  <script src='https://cdnjs.cloudflare.com/ajax/libs/marked/1.2.7/marked.min.js'></script>
  <script>${script}</script>
</body>
main.js
window.onload = function() {
  // 入力されるたびに発火させる
  $input.oninput = () => {
    // 入力された markdown を html に変換して表示
    $output.innerHTML = marked($input.value);
  };
  
  // 初期値を入れて変換しておく
  $input.value = `# markdown editor\n\n- hoge\n- foo\n- bar`;
  $output.innerHTML = marked($input.value);
};

変換部分は marked.js に頼っているものの, かなり JavaScript のコードが短いのが分かるかと思います.

処理の流れとしては, textarea に input イベントを登録し, 何か値が入力されるたびに markdown を html に変換して結果表示用の DOM に代入して表示しています.

つまり, JavaScript ほぼ3行で markdown editor を実現しています.

$input.oninput = () => {
  $output.innerHTML = marked($input.value);
};

document.getElementByIddocument.querySelector といったコードも一切ありません.

これは, JavaScript で参照する DOM に予め $input$output といった id を指定してグローバル変数に格納しておくことで, 処理開始時から変数にアクセスできるようにしているからです.

id の名前の先頭に $ を付けることでグローバル名のバッティングの確率を下げています.

このようにちょっとしたツールであればかなり楽をして開発することができます.

おわりに

紹介しておいてなんですが, このテクニックは実際の現場ではあまりおすすめしません.

私も, ちょっとした場面で一時的に必要になったツールを作るときや, メンバーにプログラミングを教えるときのライブコーディング時等でしか使わないです.

なぜなら, グローバル空間の汚染はバグの温床となるからです.
名前のバッティング問題や予期せぬ場面での値の書き換えといったリスクが跳ね上がります.

なので, 規模の小さな開発やスピード, ライブ感を優先するときのショートハンドテクニックとして活用してもらえると幸いです.

Reference

この tips に関する仕様です.

https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object