为什么“#.id”在CSS/jQuery中是一个坏的选择器,但它在HTML锚中工作?

前端之家收集整理的这篇文章主要介绍了为什么“#.id”在CSS/jQuery中是一个坏的选择器,但它在HTML锚中工作?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用JSDoc。它生成一个周期为的ids
<a id=".someMethodName"></a>

如果页面的另一部分

<a href="#.someMethodName"></a>

这完美的。单击第二个锚点滚动到第一个。

但是,document.querySelector和jQuery都不会找到锚点。

为什么浏览器本身接受这个锚点,但jQuery和querySelector不?

test("document.querySelector('#.someMethodName')",function() {
  document.querySelector('#.someMethodName');
});
test("$('#.someMethodName')",function() {
  $('#.someMethodName');
});

function test(msg,fn) {
  try {
    var result = fn();
    log(msg,result);
  } catch(e) {
    log(msg,e);
  }
}

function log() {
  var pre = document.createElement("pre");
  pre.appendChild(document.createTextNode(Array.prototype.join.call(arguments," ")));
  document.body.appendChild(pre);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#.someMethodName">click here to go to anchor and see errors</a>
<pre>
put
some
text
here
so
the
page
is
long
enough
that
when
we
click
the
anchor
the
browser
has
as
a
place
to
scroll
that
is
off
screen
otherwise
we'd
have
no
way
to
see
if
it
worked
or
not
</pre>
<a id=".someMethodName">we should scroll to here</a>
<p>did we make it?</p>
<hr/>

解决方法

HTML5允许在ID属性值中有一个句点,而浏览器已经处理了这个没有任何问题几十年(这就是为什么HTML 4中的限制 – 本身不是由HTML定义,而是由SGML定义,在HTML5中放宽,现在免于SGML的遗产包装)。所以问题不在于属性值。

RFC 3986定义的片段标识符的语法是:

06000

其中pchar的字符集包括句点。所以.someMethodName是一个有效的片段标识符,这就是为什么< a href =“#。someMethodName”>作品。

但#.someMethodName不是有效的选择器,原因有两个:

> ID选择器由#后跟一个ident和an ident in CSS cannot contain a period组成。
>因此,周期保留用于类选择器(类似地,由一个周期后跟一个ident)。

简而言之,解析器期待一个CSS ident后的#,但没有找到一个,因为。直接跟随它,使选择器无效。这是令人惊讶的,因为ID选择器的符号实际上是基于片段标识符的URI表示法,这是因为它们都以#符号开始,以及它们都用于引用由该标识符在文档中唯一标识的元素。期望在URI片段中工作的任何东西也可以在ID选择器中工作并不是不合理的 – 并且在大多数情况下它是真的。但是因为CSS有自己的语法,它不一定与URI语法相关(因为它们是两个完全不相关的标准1),你会得到像这样的边缘情况。

由于句点是片段标识符的一部分,因此需要使用反斜杠将其转义,以便在ID选择器中使用它:

#\.someMethodName

不要忘记,你需要在JavaScript字符串中转义反斜杠本身(例如,用于document.querySelector()和jQuery):

document.querySelector('#\\.someMethodName')
$('#\\.someMethodName')

1几年前,一个名为使用CSS选择器作为片段标识符的提议形成了一个W3C Community Group(其中我是一个成员),你可以想象,一个有趣的方式结合了这两种技术。这从来没有起飞,然而,唯一已知的实现是一些浏览器扩展,甚至可能甚至不被维护。

猜你在找的CSS相关文章