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