首先查看一下querySelectorAll的文档:

querySelectorAll

返回与指定的选择器组匹配的文档中的元素列表 (使用深度优先的先序遍历文档的节点)。返回的对象是 NodeList

用法:

1
var elementList = document.querySelectorAll(selectors);
  • elementList 是一个静态的 NodeList 类型的对象.
  • selectors 是一个由逗号连接的包含一个或多个CSS选择器的字符串.
  • 如果 selectors参数中包含 CSS伪元素,则返回一个空的elementList.
  • 如果指定的选择器不合法,则抛出一个SYNTAX_ERR 异常.

如下一个element

1
2
3
<div id="123">
<div class="test"></div>
</div>

document.getElementById(‘123’)可以正常获取到该元素
document.querySelectorAll(‘#123’)则报错

我们看下Zepto中选择器的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// `$.zepto.qsa` is Zepto's css selector implementation which
// uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.
// This method can be overridden in plugins.
zepto.qsa = function(element, selector){
var found,
maybeID = selector[0] == '#',
maybeClass = !maybeID && selector[0] == '.',
nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked
isSimple = /^[\w-]*$/.test(nameOnly)
return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById
( (found = element.getElementById(nameOnly)) ? [found] : [] ) :
(element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] :
slice.call(
isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName
maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class
element.getElementsByTagName(selector) : // Or a tag
element.querySelectorAll(selector) // Or it's not simple, and we need to query all
)
}

同样的,zepto中的选择器用的就是querySelectorAll,但是对于简单情况,又可能使用getElementById/getElementsByClassName/getElementsByTagName,
所以对于上面的元素,$(‘#123’)可以获取到元素, $(‘#123 .test’)却会报错,$(‘#123’).find(‘.sddd’)可以正常获取到。
对于如下这种元素使用$(‘#1.2.3-标题’)也会报错

1
<div id="1.2.3-标题"></div>

报错信息:

VM238:1 Uncaught DOMException: Failed to execute ‘querySelectorAll’ on ‘Document’: ‘#123’ is not a valid selector.