在 ID 为数字的情况下使用 querySelector

根据我的理解,HTML5规范允许您使用如下数字的 ID。

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

我可以访问这些罚款使用 getElementById,但不与 querySelector。如果我尝试做以下操作,我会在控制台中得到 语法错误: DOM 异常12

document.querySelector("#1")

我只是好奇为什么当 HTML5规范说明数字作为 ID 是有效的时候,使用数字作为 ID 不能用 querySelector。我试过多种浏览器。

142464 次浏览

因为虽然它们在 HTML5规范中是有效的,但在 CSS 中是无效的,这就是“ query 选择器”的意思。

相反,您必须这样做: document.querySelector("[id='1']"),考虑到您可以给它一个 有意义 ID,如 message1或其他;)

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

前导数字

如果标识符的第一个字符是数字,你需要根据它的 Unicode字符来转义它。例如,字符1的代码点是 U + 0031,因此可以转义为000031或31。

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

所以你的代码最终会变成(CSS 第一,JS 第二) :

#\31  {
background: hotpink;
}


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

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

我最后用的是 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!

来自 W3C 文档 属性选择器语法

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

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

如果使用 ID 生成器实用程序生成标识符,则最终可能会得到前导数字的字母数字 ID。

一个快速修复方法是从生成器的 SEED 中省略数字(如果可以修改的话) ,或者总是在生成的 id 后面添加一个字符串。

这里有一个函数,我刚才为处理领导数字 ID 的 CSS 选择器,它是 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 );




若要在查询选择器中使用动态 ID,请使用简单的代码。

this.template.querySelector("[id='"+divId+"']");

如果您正在进行迭代,并且希望访问 id,那么请检查这段代码。 我对帐户对象进行了迭代,并在 LWC 上使用了可点击事件:

<template for:each={accounts.data} for:item="acc">
<div key={acc.Id} id={acc.Id} class="box" onclick={handleClick}>
{acc.Name}
</div>
</template>

我希望在调用 div 上的 onclick事件时使用其 ID 访问 div 数据。

handleClick(event){
event.dataTransfer.setData("divId", event.target.id);
var divId = event.dataTransfer.getData("divId");


//Using the divId in querySelector
var Element = this.template.querySelector("[id='"+divId+"']");


}

使用 CSS.escape (无效 ID)是一种很有前途的解决方案。

解决方案视频: https://youtu.be/rH5IVJKmSOE

以你为例: QuerySelector (“ #”+ CSS.escape (’1’))

或者

QuerySelector (“[ id =’1’]”)

CSS 规范说:

中的标识符(包括元素名称、类和 ID) 选择器)只能包含字符[ a-zA-Z0-9]和 ISO10646 字符 U + 00 A0及以上,加上连字符(-)和下划线 (_) ; 他们不能从一个数字开始,两个连字符,或一个连字符 后跟一个数字。标识符也可以包含转义字符 以及任何 ISO10646字符作为数字代码(请参阅下一项) 例如,标识符“ B & W?”可以写为“ B & W?”或“ B 26 W3F”。

Https://www.w3.org/tr/css2/syndata.html#characters