JavaScript querySelectorAll转义句点标准引用



在Blink bug 1045868中,我提到querySelectorAll不适用于句点。我收到的回复是:

这是符合规范的。标识符中包含点的选择器需要转义,否则它们被视为类选择器的开始。

不同的渲染引擎处理这种差异,因此肯定存在某种不一致性;问题是确定不符合,以便正确解决问题。

querySelectorAll的初始定义在哪里?或者,如果我与一个或多个懒惰的开发人员打交道,这是暗示的在哪里?

选择器级别3:4。选择器语法

选择器中的字符可以根据与CSS相同的转义规则使用反斜杠进行转义。[CSS21]。

CSS21:4.1.3字符和大小写

在CSS中,标识符(包括选择器中的元素名称、类和ID(只能包含字符[a-zA-Z0-9]和ISO 10646字符U+00A0及更高版本,以及连字符(-(和下划线(_(;它们不能以数字、两个连字符或一个连字符后跟一个数字开头。标识符也可以包含转义字符

.(句号(是U+002E,因此不允许将字符作为标识符的一部分,因此必须进行转义。

#music_playlist-2.7中的.将指示这种类型的选择器#idIdentifer.classIdentifer,但.7不是有效的类标识符,因为标识符不能以数字开头,因此根据选择器的解析器的实现方式,它可能会忽略选择器中的错误,并将.7计数为前一标识符的一部分,但这是不正确的,至少我在规格中找不到任何可以证明这一点的地方:

选择器级别3:4。选择器语法

选择器是由组合子分隔的一个或多个简单选择器序列的链。一个伪元素可以被附加到选择器中的最后一个简单选择器序列。

简单选择器的序列是一个简单选择器的链,这些选择器不被组合子分隔。它总是以类型选择器或通用选择器开头。序列中不允许使用其他类型选择器或通用选择器。

简单选择器类型选择器用选择器属性选择器>、class选择器1、1ID选择器2或pseudo-class

通用选择器,写为CSS限定名称[CSS3NAMESPACE],带有星号(*U+002A(作为本地名称,[…]如果由*[…]表示的万能选择器单选择器选择器序列的唯一组件或后面紧跟着伪元素,则可以省略CCD_ 11并且暗示通用选择器的存在。

因此,如果您想在querySelectorAll中使用IDmusic_playlist-2.7,请这样写:

document.querySelectorAll('#music_playlist-2\.7 input[name="payment_form_function"]');

或者,如果你想在css规则中使用它:

#music_playlist-2.7 input[name="payment_form_function"] {
color: red;
}

可选的选择器是属性括号:

const lazyDevs = document.querySelectorAll('[class="lazy.dev"]');

下面的演示展示了上述语句的工作原理以及修复DOM中问题的方法(仍有CSS和JavaScript需要修复(。


演示

/*
The attribute selector works: 
'[class="lazy.dev"]'
*/
const lazyDevsA = document.querySelectorAll('[class="lazy.dev"]');
console.log(`'[class="lazy.dev"]' ~~~ ${lazyDevsA.length} ~~~~~~~~~~~ 👍`);
console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~');
/*
In order to find all of the malformed class selectors:
'[class*="."]'
*/
const lazyDevsB = document.querySelectorAll('[class*="."]');
console.log(`'[class*="."]' ~~~~~~~~~ ${lazyDevsB.length} ~~~~~~~~~~~ 👍`);
console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~');

/*
- This function will replace the first string parameter
(rem) with the second string parameter (add)  
- Then replaces the offending className with the new
className on every tag within the NodeList
*/
function lazyDevKiller(rem, add) {
const NodeList = document.querySelectorAll('[class*="'+rem+'"]');
NodeList.forEach(node => {
let selector = node.className;
let classAtt = selector.split(rem).join(add);
node.className = "";
node.className = classAtt;
});
}
/*
- This will find all tags that have one or more dots:
"." (periods or full stops) in their className.
- It will replace each "." with a dash "-" and assign
the new className to each tag.
- Note: the elements in the result window are labeled:
"lazy-dev"
*/
lazyDevKiller('.', '-');
aside {
font: 700 1.25rem/1.5 "Comic Sans MS", cursive, sans-serif;
color: blue;
background: goldenrod;
text-align: center;
border-bottom: 3px ridge rgba(0, 0, 255, 0.3);
width: 20vw;
margin: 20px 10px;
display: inline-block;
}
aside::after {
content: ' 'attr(class);
}
<aside class='lazy.dev'></aside>
<aside class='lazy.dev'></aside>
<aside class='lazy.dev'></aside>
<aside class='lazy.dev'></aside>

例如,如果您有这个元素:

<div id='foo.bar'>

您可以使用进行选择

document.getElementById('foo.bar')

如果你想选择它querySelector,你必须退出点

document.querySelector('#foo\.bar')

最新更新