选择器表达式
术语约定
- 选择器表达式:如,"div>p"
- 并列选择器表达式:如,"div p"
- 块表达式:如,"div>p"中的"div","p"
- 块表达式类型:如,"div"的类型是TAG,"div.red"则是TAG+CLASS
- 块间关系符:如,"div>p"中的">"
选择器表达式的组成
- 块表达式
- 简单表达式:ID,CLASS,TAG
- 属性表达式:ATTR
- 伪类表达式PSEUDO:
- 位置伪类:POS
- 子元素伪类CHILD
- 内容伪类
- 可见伪类
- 表单伪类
- 块间关系符:">" , "" , "+"和"~"
查找思路:以"div.red>p"为例
查找思路
1.从左向右:先查找"div.red",再查找"p";(不断缩小查找范围)
2.从右到左(Sizzle核心查找方式):先查找:"p",再查找"div.red";(先查找后过滤,效率比从左到右高;)
步骤
- 解析出:块表达式和块间关系符的集合
- 先查找div.red元素,再查找p元素
- 处理div.red和p之间的关系符">"
- 从左到右:找到div.red匹配的子元素集合,再查找匹配p的元素
- 从右到左:查找匹配p元素的父元素是否为div.red
Sizzle总体架构
/**书籍:jQuery技术内幕-深入解析jQuery架构设计与实现
*
* 如果浏览器支持querySelectorAll(),则调用该方法
* 如果不支持,Sizzle模拟该方法的行为
*
* 术语和约定[重点]
* 1.选择器表达式:"div>p"
* 2.并列选择器表达式:"div,p"
* 3.块表达式:"div>p"中的"div","p"
* 4.快表达式类型:div的类型是TAG, ".red"的类型类型是CLASS,"div.red"的类型是TAG+CLASS
* 5.块间关系符:"div>p"中的>
*
* 选择器表达式有块表达式和块间关系符组成
* 1.块间关系符
* 2.块表达式
* a.简单表达式:ID,CLASS,TAG
* b.属性表达式:ATTR
* c.伪类表达式:1.位置伪类:POS; 2.子元素伪类:CHILD; 3.内容伪类; 4.可见伪类; 表达伪类
*/
(function(window){
var Expr;
//***********************公开方法***************************************** */
/**
* 查找与选择器表达式selector匹配的元素集合:引擎入口
* @param {*} selector CSS选择器表达式
* @param {*} context DOM元素或文档对象
* @param {*} results 结果集
* @param {*} seed 可选元素集合,Sizzle()将从该元素集合中过滤出匹配选择器表达式的元素集合
* @returns
*/
function Sizzle(selector,context,results,seed){
return results;
};
//用选择器表达式expr对元素集合set进行过滤
Sizzle.matches = function( expr, elements ) {
return Sizzle( expr, null, null, elements );
};
//检查元素node是否匹配选择器表达式expr
Sizzle.matchesSelector = function( elem, expr ){
};
//***********************内部使用********************************** */
//选择器表达式过滤
Expr = Sizzle.selectors = selectors;
Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
// Easy API for creating new setFilters
//位置伪类过滤函数集
function setFilters() {}
setFilters.prototype = Expr.filters = Expr.pseudos;
Expr.setFilters = new setFilters();
//*******************工具方法******************************************** */
//排序去重
Sizzle.uniqueSort = function(results){
};
//检查元素a是否包含b
Sizzle.contains = function( context, elem ) {
};
Sizzle.error = function(msg){
throw new Error("Syntax error,unrecognized expression: "+msg);
};
//********************暴露出去******************************* */
//Expose
var _sizzle = window.Sizzle;//未加载jQuery前的Sizzle属性
//如果名称冲突, 用这个方法取另外的名称
Sizzle.noConflict = function(){
if(window.Sizzle === Sizzle)
{
window.Sizzle = _sizzle;
}
return Sizzle;
}
//引入方式
if(typeof define === "function" && define.amd){//AMD(nodejs):Asynchronous Module Definitoin
define(function(){
return Sizzle;
});
}else if(typeof module !== "undefined" && module.exports){
module.exports = Sizzle;//ES6
}else{
window.Sizzle = Sizzle;
}
})(window);