使用带有数字的ID的querySelector


94

根据我的理解,HTML5规范使您可以使用ID这样的数字。

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

我可以使用,getElementById但不能使用querySelector。如果尝试执行以下操作,则会在控制台中收到SyntaxError:DOM异常12

document.querySelector("#1")

我很好奇,querySelector当HTML5规范说数字有效时,为什么不能将数字用作ID起作用。我尝试了多种浏览器。


1
我不认为HTML5规范说的是有效的。我会仔细检查...
beautifulcoder

3
@beautifulcoder他们有效
dsgriffin

1
没关系,根据validator.w3.org/检查使用数字是否有效。也许现代浏览器尚未完全实现该标准?
beautifulcoder

Answers:


108

它是有效的,但是需要一些特殊的处理。从这里:http : //mathiasbynens.be/notes/css-escapes

前导数字

如果标识符的第一个字符是数字,则需要根据其Unicode代码点对其进行转义。例如,字符1的代码点为U + 0031,因此可以将其转义为\ 000031或\ 31。

基本上,要转义任何数字字符,只需在其前面加上\ 3并附加一个空格字符()。是的Unicode!

因此,您的代码最终将显示为(首先是CSS,然后是JS):

#\31  {
    background: hotpink;
}

document.getElementById('1');
document.querySelector('#\\31 ');

值大于9的语法是什么?我无法与ID,如10得到这个工作
贝瑞蓝

5
您需要在第一个字符后添加一个空格:#\\31 0-您可以参考mothereffingcssescapes.com
丹尼斯

感谢您的跟进和链接!
Berry Blue

1
请注意,仅当十六进制数字的字符紧随转义序列之后才需要空格,以便将该字符与转义序列区分开。有关更多详细信息,请参见w3.org/TR/CSS21/syndata.html#characters
BoltClock

83

因为尽管它们在HTML5规范中有效,但在CSS中无效,这就是“查询选择器 ”的含义。

取而代之的是,您必须执行以下操作:document.querySelector("[id='1']"),考虑到您可以给它提供有意义的 ID(例如message1或类似的东西),所以这很费劲;


1
您无需“必须”-有一种方法可以将ID选择器与前导数字一起使用。我同意,尽管最好有一个有意义的ID。
丹尼斯

9
UUID可以以数字开头。
阿方索西川

20

我需要一种自动化的方法。最近的更改意味着所使用的id值不再是简单的字母字符,而是包含数字和特殊字符。

我最终使用了CSS.escapehttps : //developer.mozilla.org/en-US/docs/Web/API/CSS/escape

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

首先,这是失败的情况:

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

现在使用CSS.escape

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

看看它如何正确更改为show After,表明选择器有效!


到今天为止,当您需要处理一些您无法控制的奇怪ID时,这是最干净的解决方案,也因为所有现代浏览器都支持该解决方案。
LasaleFamine

3

从W3C文档属性选择器语法

属性值必须是有效的CSS标识符或字符串。

因此,数字或带有前导数字的字母数字字符串不符合有效的标识符的条件。

如果使用ID生成器实用程序生成标识符,则可能会以带有前导数字的字母数字ID结尾。

一个快速的解决方案是要么忽略生成器的SEED中的数字(如果可以修改),要么总是将字符串附加到生成的ID上。


2

这是我刚才为处理CSS选择器中的前导数字ID编写的函数,它是IE安全的,而CSS.escape则不是。

在使用选择器之前,请使其通过以下cleanSelector函数:

var cleanSelector = function(selector){
    (selector.match(/(#[0-9][^\s:,]*)/g) || []).forEach(function(n){
        selector = selector.replace(n, '[id="' + n.replace("#", "") + '"]');
    });
    return selector;
};

var myselector = ".dog #980sada_as div span#aside:hover div.apple#05crab:nth-of-type(2), .ginger #2_green_div, div.cupcake #darwin p#23434-346365-53453";

var clean_myselector = cleanSelector(myselector);

// print to show difference
console.log(myselector);
console.log(clean_myselector);

//use the new selector like normal
var elems = document.querySelectorAll( clean_myselector ); 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.