- <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/>
解决方法
由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(其中我是一个成员),你可以想象,一个有趣的方式结合了这两种技术。这从来没有起飞,然而,唯一已知的实现是一些浏览器扩展,甚至可能甚至不被维护。