Using querySelector with IDs that are numbers

2019-01-04 10:29发布

From what I understand the HTML5 spec lets you use IDs that are numbers like this.

<div id="1"></div>
<div id="2"></div>

I can access these fine using getElementById but not with querySelector. If I try do the following I get SyntaxError: DOM Exception 12 in the console.

document.querySelector("#1")

I'm just curious why using numbers as IDs does not work querySelector when the HTML5 spec says these are valid. I tried multiple browsers.

3条回答
叛逆
2楼-- · 2019-01-04 10:52

It is valid, but requires some special handling. From here: http://mathiasbynens.be/notes/css-escapes

Leading digits

If the first character of an identifier is numeric, you’ll need to escape it based on its Unicode code point. For example, the code point for the character 1 is U+0031, so you would escape it as \000031 or \31 .

Basically, to escape any numeric character, just prefix it with \3 and append a space character ( ). Yay Unicode!

So your code would end up as (CSS first, JS second):

#\31  {
    background: hotpink;
}

document.getElementById('1');
document.querySelector('#\\31 ');
查看更多
我想做一个坏孩纸
3楼-- · 2019-01-04 10:54

I needed an approach which was automated. A recent change meant the id values used were no longer simple alphabetic characters and included numbers and special characters.

I ended up using CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

console.log(CSS.escape('1'));

First, this is the failing case:

const theId = "1";
document.querySelector(`#${theId}`);
const el = document.querySelector(`#${theId}`);
el.innerHTML = "After";
<div id="1">Before</div>

And now using CSS.escape:

const theId = "1";
const el = document.querySelector(`#${CSS.escape(theId)}`);
el.innerHTML = "After";
<div id="1">Before</div>

See how it correctly changes to show After, demonstrating the selector worked!

查看更多
冷血范
4楼-- · 2019-01-04 11:02

Because while they are valid in the HTML5 spec, they are not valid in CSS, which is what "query selector" means.

Instead, you would have to do this: document.querySelector("[id='1']"), which is very long-winded considering you could give it a meaningful ID like message1 or something ;)

查看更多
登录 后发表回答