メモ HTMLJavascript

    Document.querySelector() で先頭が数字のIDを指定するとエラーが起きる。

    2022.11.23

    こんにちはjunです。最近、editor.jsだったり色々バニラJSを触る機会がありました。特定のNodeを取得する時にdocument.querySelector()を使用することでCSS・jqueryライクに要素を取得できます。今回はIDを持つ要素をgetByElementId()を使わず、querySelector()を用いてquerySelector("#~~~")と取得した時に遭遇したエラーについてです。

    タイトルの通りなのですが、querySelector()で先頭が数字のIDを指定するとエラーが起きます。

    document.querySelector("#16test");
    // VM490:1 Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '#16test' is not a valid selector.
    

    簡単にコンソールでチェックできます。「not a valid selector」の通り、有効なセレクタじゃないよと怒っています。なぜこんなことが起きるのかを調べたところ、querySelector()はCSSセレクタの仕様を使っており、CSSのIDセレクタは「#の後に数字をつけてはいけない」という仕様があるからです。

    Stackoverflow https://stackoverflow.com/questions/37270787/uncaught-syntaxerror-failed-to-execute-queryselector-on-document

    上記のStackoverflowの回答が役に立ちました。HTML5の仕様としてはIDの最初の文字に数字を入れることは問題ありません。しかしCSS3のIDセレクタの仕様ではなんと、#のあとに数字を使用してはいけないと確かに書かれています。詳細はW3Cのこちらのページにあります。

    they cannot start with a digit, two hyphens, or a hyphen followed by a digit.

    第一の解決策はgetElementById()を使うことです。そう思うと、本来DOMにIDを持つ要素は必ず一つなのでgetElementById()を使えばいいのに、なんでquerySelector()を使っていたんだろうか?と思っていたら、ランダムに生成したIDをもつ要素配下のある子要素を取得する処理を実装する際、querySelector(`#{id} .item`)みたいな感じで実装してた時でした。

    この場合ランダムに生成されるIDに数字が含まれないようにするか、getElementById(id)?.querySelector(".item")として一旦getElementById()を使ってからquerySelector()を使うといいかなと思います。

    Copyright © 2021 jun. All rights reserved.