zepto-selector.js简单分析
zepto 的selector模块是对jquery扩充选择器(jquery-selector-extensions)的部分实现。比如这样的选择方法:$('div:first') 和 el.is(':visible')。
下面是原代码,简单的写了一些注释~
;(function($){
var zepto = $.zepto, oldQsa = zepto.qsa, oldMatches = zepto.matches
/*
* 检察一个元素是否可见。除了要判断display是否是none之外,还判断了width和height是否是0,
双叹号是强制转化成boolean类型
*/
function visible(elem){
elem = $(elem)
return !!(elem.width() || elem.height()) && elem.css("display") !== "none"
}
// 实现的是jquey选择器扩展的一部分
// http://api.jquery.com/category/selectors/jquery-selector-extensions/
//
// 每一个filter函数的参数都能接受当前值,所有考虑范围内的节点和括号中的值
// this就是当前被考虑的node. 函数返回的是node(s), null 或者是undefined
//
// 复杂的选择器是不被支持的,比如下面的:
// li:has(label:contains("foo")) + li:has(label:contains("bar"))
// ul.inner:first > li
var filters = $.expr[':'] = {
visible: function(){ if (visible(this)) return this },//可见
hidden: function(){ if (!visible(this)) return this },//不可见
selected: function(){ if (this.selected) return this },//选中
checked: function(){ if (this.checked) return this },//勾选中
parent: function(){ return this.parentNode },//父节点
first: function(idx){ if (idx === 0) return this },//第一个元素
last: function(idx, nodes){ if (idx === nodes.length - 1) return this },//最后一个元素
eq: function(idx, _, value){ if (idx === value) return this },//相同的元素
contains: function(idx, _, text){ if ($(this).text().indexOf(text) > -1) return this },//内容含有的元素
has: function(idx, _, sel){ if (zepto.qsa(this, sel).length) return this }//
}
var filterRe = new RegExp('(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*'),//一个强大的正则表达式用来分解选择器的的,见下面
childRe = /^\s*>/,
classTag = 'Zepto' + (+new Date())
function process(sel, fn) {//分解选择器为三部分,第一部分是选择器本身,第二部分是选择器的值filter中的函数名称,第三部分是参数
//例如:(1)filterRe.exec(":eq(2)")
//得到的结果:[":eq(2)", "", "eq", "2"]
//(2)filterRe.exec(":visible")
//得到的结果:[":visible", "", "visible", undefined]
// quote the hash in `a[href^=#]` expression
sel = sel.replace(/=#\]/g, '="#"]')
var filter, arg, match = filterRe.exec(sel)
if (match && match[2] in filters) {
filter = filters[match[2]], arg = match[3]//filter为filters中对应的函数
sel = match[1]
if (arg) {
var num = Number(arg)
if (isNaN(num)) arg = arg.replace(/^["']|["']$/g, '')
else arg = num
}
}
return fn(sel, filter, arg)
}
zepto.qsa = function(node, selector) {
return process(selector, function(sel, filter, arg){
try {
var taggedParent
if (!sel && filter) sel = '*'
else if (childRe.test(sel))
// support "> *" child queries by tagging the parent node with a
// unique class and prepending that classname onto the selector
taggedParent = $(node).addClass(classTag), sel = '.'+classTag+' '+sel
var nodes = oldQsa(node, sel)
} catch(e) {
console.error('error performing selector: %o', selector)
throw e
} finally {
if (taggedParent) taggedParent.removeClass(classTag)
}
return !filter ? nodes :
zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))
})
}
//
//selector和function(sel,filter,arg){}传到process中,
//处理完后,运行function(sel,filter,arg){},其中sel是selector经过强大正则之后的第二块,filter是filters中对于的函数,arg是selector中的参数
zepto.matches = function(node, selector){
return process(selector, function(sel, filter, arg){
return (!sel || oldMatches(node, sel)) &&
(!filter || filter.call(node, null, arg) === node)
})
}
})(Zepto)
zepto-selector.js简单分析的更多相关文章
- 迷你版jQuery——zepto核心源码分析
前言 zepto号称迷你版jQuery,并且成为移动端dom操作库的首选 事实上zepto很多时候只是借用了jQuery的名气,保持了与其基本一致的API,其内部实现早已面目全非! 艾伦分析了jQue ...
- Zepto核心模块源代码分析
一.Zepto核心模块架构 Zepto核心模块架构图 该图展示了Zepto核心模块架构代码的组织方式.主要分为私有变量.函数和暴露给用户的所有api. Zepto核心模块架构代码 该图展示了Zepto ...
- jquery原理的简单分析,让你扒开jquery的小外套。
引言 最近LZ还在消化系统原理的第三章,因此这部分内容LZ打算再沉淀一下再写.本次LZ和各位来讨论一点前端的内容,其实有关jquery,在很久之前,LZ就写过一篇简单的源码分析.只不过当时刚开始写博客 ...
- 简单分析JavaScript中的面向对象
初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...
- Tourist.js – 简单灵活的操作指南和导航插件
Tourist.js 是一个基于 Backbone 和 jQuery 开发的轻量库,帮助你在应用程序创建简单易用的操作指南和导航功能.相比网站,它更适合用于复杂的,单页网站类型的应用程序.Touris ...
- JS简单示例
首先感谢海棠学院提供的优质视频资源 学习总是一个由简单到难的过程,由浅入深,一步一个脚印,将学过的点玩的深入一点,才能有所进步,单学习总是枯燥而乏味的,切忌焦躁; 示例代码另存放在github:htt ...
- howdoi 简单分析
对howdoi的一个简单分析. 曾经看到过下面的这样一段js代码: try{ doSth(); } catch (e){ ask_url = "https://stackoverflow.c ...
- python2.7 爬取简书30日热门专题文章之简单分析_20170207
昨天在简书上写了用Scrapy抓取简书30日热门文章,对scrapy是刚接触,跨页面抓取以及在pipelines里调用settings,连接mysql等还不是很熟悉,今天依旧以单独的py文件区去抓取数 ...
- 高德JS依赖分析工程及关键原理
一.背景 高德 App 进行 Bundle 化后,由于业务的复杂性,Bundle 的数量非常多.而这带来了一个新的问题——Bundle 之间的依赖关系错综复杂,需要进行管控,使 Bundle 之间的依 ...
随机推荐
- 修改ftp端口为50021
1. 配置 2. 增加防火墙规则 netsh firewall set portopening tcp 50021 ftp-50021 enable 3. 重启服务 net stop FileZill ...
- android下载简单工具类
功能是实现下载文件,图片或MP3等,为了简单起见使用单线程,此代码为MarsAndroid教程的复制品,放在此处,留着参考. 首先是一个得到字节流随后保存到内存卡上的工具类: package com. ...
- C# 获取当前,相对,绝对路径
一.C#获取当前路径的方法: 1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName -获取模块的完整路径. 2. ...
- hihocoder #1052 基因工程
传送门:基因工程 这道题拖了好久,一直没有清晰的思路. 当然,$K\le\frac{N}{2}$时,比较简单.下面我着重讲一下当$K>\frac{N}{2}$,即前$K$个字符与后$K$个字符有 ...
- Centos下查看占用端口并关闭进程方法
1.查看端口占用情况:netstat –tlnp (加p可以看到是哪个进程占用了端口); 也可以用grep查找对应的被占用的端口,键入netstat –tlnp | grep 3306可以看到PI ...
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
- iOS - 类簇
类簇是在Objective-C中Foundation Framework中广泛使用的一种设计模式 1.发现类簇(Class Cluster)的踪迹 //*> 执行下面代码 id obj1 = [ ...
- Linux学习之CentOS--CentOS6.下Mysql数据库的安装与配置
跟着配置,顺利配置完成 http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html
- asp.net 性能优化
在MSDN网络课堂中下载了一些九月份的网络讲座.有很多还是很有意义的.<ASP.NET系列讲座之一:性能与缓存>是由微软开发工具专家王立楠讲授.王先生的讲解非常清晰,课件也很详细,虽然是网 ...
- 写Action的三种方法
Action类似于servlet,在用户对浏览器输入url访问的时候充当控制器的角色.它在访问时产生,执行execute()之后就销毁了. 写Action是代理事务,它实现的三种方式是: (1)POJ ...