在CSS类选择器中转义字符

问题描述 投票:10回答:3

我正在努力实现 这个W3 描述CSS类选择器中的字符转义。

我在使用 abc\20 def 句法,在转义序列后放置一个空格,以确保 def 不被误读为字符代码的一部分。

具体来说,试图把 abc\XY def 到一个HTML类属性中,或者到一个类似于 jQuery().addClass('abc\\20 def') (该 \\ 这里是JS字符串文字语法的一部分,字符串值本身有一个斜杠)都会给元素两个类。abc\20def.

是不是这种语法就是不好实现,我应该坚持使用六位数前导零的形式?还是说那篇文档只参考了CSS代码中的转义格式,而HTML属性的jQuery参数需要一些不同形式的空格字符转义?

编辑: 非常感谢大家的解释!我现在明白了这种语法只适用于CSS代码,而不是HTML属性或Javascript中设置的类名本身。

我现在明白了,这种语法只适用于CSS代码,而不是HTML属性或Javascript中设置的类名本身。

这也意味着,指定为空白的字符 不能 发生在CSS类值中,没有一种转义机制允许它们被添加。(具体来说,如果我的理解没错的话,CSS选择器中的 .abc\20 def 是有效的,并选择具有 abc def但没有意义,因为没有元素可以拥有这个类)。)

对于我的具体用例,它涉及到 映射任意值(这 可以 有白色空间)到有效的类名我需要定义我自己的转义方案。将空白处替换为 -_ (谢谢 Praveen)是一种可能性;如果需要一对一的映射,用六位数的 Unicode 十六进制值代替它们(比如......)是更稳健的方法。"abc def" -> "abc\000020def" 是一个更稳健的方法。

需要注意的是,这种替换会影响到类名本身--要想引用类的 abc\000020def 在CSS中,反斜杠必须再次转义,以形成选择器。.abc\\000020def.

javascript html css-selectors
3个回答
6
投票

你把DOM中的类名和CSS中要求的转义版本搞混了。类名是按原样指定的。

elt.classList.add('foo:bar')

它是当这个在CSS文件中被引用(或其他CSS选择器上下文,如 querySelector),它必须被转义。

.foo\:bar { color: red; }

这同样适用于您选择使用数字转义的情况。

elt.classList.add('1234');

.\31 234 { color: red; }

然而,任何数量的转义都不允许你在类名中使用空格。空格是绝对保留的,用于在DOM上分隔多个类名。className 属性。


9
投票

简答。DOM会将你传递给它的任何选择符解析为字符串。如果(DOM解析的)结果包含空格或非分隔符,它们将被视为类分隔符。


你不应该担心jQuery或任何其他ECMAScript会把用于结束转义块的空格误解为类分隔符。

简单地说,因为 他们不负责这种匹配. 文档对象模型是。解释转义CSS类的同一个DOM。因此,如果一个转义的类名在你的样式表中工作,如果被任何JavaScript库传递,它将作为一个选择器工作。

但有一个条件。 它被传递给DOM的形式是它能理解的。一个能理解的形式 在CSS中工作.

现在,让我们假设,出于语义的原因,你想使用类 100% 的元素上。你需要至少转义第一个和最后一个字符,以使你的选择器工作。中间的字符可能会被转义,也可能不会。可能的选择器,都是在DOM级别上翻译为 100% 类名,将是。

  • .\31 00\25
  • .\31 0\30\25
  • .\31\30 0\25
  • .\31\30\30\25
  • .\31 \30 \30 \25

你已经知道,有更多的 套用CSS方法. 然而,这适用于所有。

当你把一个选择器传递给jQuery或JavaScript时,它会把它当作一个字符串并传递给DOM解析器。然而,这些库有自己的转义机制,允许我们做一些花哨的事情。所以,为了让上述任何一个选择符能够传递给DOM解析器,你需要对反斜杠进行转义,这样它们就不会被JavaScript误解为转义字符而从字符串中删除。

基本上,你需要把反斜杠加倍。 以下任何一种都可以。

  • .\\31 00\\25,
  • .\\31 0\\30\\25,
  • .\\31\\30 0\\25
  • .\\31\\30\\30\\25
  • .\\31 \\30 \\30 \\25

这是一个片段。测试一下。添加带有类的元素 0% 你会发现它们没有被选中。因为DOM解析器会将上述任何一个选择器变成 100% 对照 100% 类的元素。

$('.\\31\\30\\30\\25>div').on('click', function(){
  var positions = ['first','second','third'];
  alert('You clicked the ' + positions[$(this).index()] + ' div.');
})
.\31 0\30\25 > div{
  padding: 20px;
}
.\31 00\25 > *:first-child {
  color: red;
}

.\31\30 0\25 > *:nth-child(2) {
  color: blue;
}
.\31\30\30\25 > *:last-child {
  color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    <div class="100%">
        <div>first</div>
        <div>second</div>
        <div>third</div>
    </div>

回到你的例子 (abc\\20 def),它的解析和行为将完全像 abc def. 空间当出现在类名字符串的最终结果中时。将被解释为类定界符。. 这适用于两种情况 \x20\xa0 空间和非断裂空间),这是预期的行为。

作为一个有趣的(琐碎的)说明,如果出于某些邪恶的原因,你想让人们很难对你的应用程序进行风格化,你可以随时添加一个 command 类型字符到类名。这里有一个例子。

$('.space').removeClass('\x73\x70\x61\x63\x65').addClass('\x1a\x73\x70\x61\x63\x65');
.space {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="space">
  inspect me, i should be red!
</div>

1
投票

我想你可以用 class="abc&amp;#x0020;def" 来解决这个问题

© www.soinside.com 2019 - 2024. All rights reserved.