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简单分析,布布扣,bubuko.com

时间: 2024-10-24 03:00:45

zepto-selector.js简单分析的相关文章

[JS][easyui]jQuery EasyUI Datagrid VirtualScrollView视图简单分析

 大家都知道EasyUI的Datagrid组件在加载大数据量时的优势并不是很明显,相对于其他一些框架,如果数据量达到几千,便会比较慢,特别是在IE下面.针对这种情况,我们首要做的是要相办法优化datagrid组件的各方面性能,不过任何事情都是可以变通解决的,virtualScrollView就是一种不错的解决方案. virtualScrollView的准则就是尽量少画tr到table里,表格的高度是有限的,而用户的可见区域是很有限的,所以数据量很大的时候,是没有必要将所有数据数据都画到表格中

netty 源码简单分析一

周末简单看了下netty5的源码,只看懂了个大概,记录下成果,方便下次再看的时候回忆. 上服务端代码: public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.grou

kafka 0.8.1 新producer 源码简单分析

1 背景 最近由于项目需要,需要使用kafka的producer.但是对于c++,kafka官方并没有很好的支持. 在kafka官网上可以找到0.8.x的客户端.可以使用的客户端有C版本客户端,此客户端虽然目前看来还较为活跃,但是代码问题还是较多的,而且对于c++的支持并不是很好. 还有c++版本,虽然该客户端是按照c++的思路设计,但是最近更新时间为2013年12月19日,已经很久没有更新了. 从官方了解到,kafka作者对于现有的producer和consumer的设计是不太满意的.他们打算

JS简单示例

首先感谢海棠学院提供的优质视频资源 学习总是一个由简单到难的过程,由浅入深,一步一个脚印,将学过的点玩的深入一点,才能有所进步,单学习总是枯燥而乏味的,切忌焦躁; 示例代码另存放在github:https://github.com/CharlesQQ/Python_Data_Analyse/tree/master/js%E5%AD%A6%E4%B9%A0 1.看一个简单的例子,有如下需求 需求:点击按钮,背景变为黄色; 分析: 步骤: 1.拿到按钮 document.getElementByid

Google Chrome 调试JS简单教程[更新]

题外话,刚开始我写这篇内容只是将自己了解的一些知识放上来,不巧的是我分析了我的来访日志,很多朋友都有这个需求,为了大家没有白来,我决定充实下这篇文章.最近更新时间2014-02-14 chrome版本: 32.0.1700.107 m 我是一名忠实Chrome迷,使用它已经快有2年的历史了,整体给我的感觉就是清爽,快速,简洁.又打小广告了……^_^,虽然我知道IE8+也有调试工具,包括火狐的什么XXBUG,但是我用过之后,个人还是十分偏爱chrome的debug. chrome对于在前端打拼的兄

【转】console.time 简单分析javascript动态添加Dom节点的性能

本文代码约定 1 el: 指的是增加直接点的DOM节点 2 totalNum: 为100000(值越大越能体现差距)指的是循环创建的DOM节点 3 for(var i=0;i<totalNum;i++){}: 我们用for来表示就好了,简写代码 如果叫你用javascript动态增加DOM节点,你有哪几种思路呢? 1 .使用innerHTML和字符串拼接 console.time("time1"); var str = ""; for{ str += &quo

console.time 简单分析javascript动态添加Dom节点的性能

Bullshit 本来想每天都更新下博客的,但是最近要考试,还有就是自己还是停留在暗自窃喜中吧(这种想法要改变).其实最近总在想,自己要怎么去管理自己的数据,每天的生活都是对自己的数据的增删查改.昨天把自己的电脑重装了,确实很多软件的存放要改地方了,之前不知道怎么去管理软件安装,所以放得乱七八糟的.说好一大堆废话之后,我最后再说一遍,管好自己的时间.数据真的比你学习东西重要. Method 本文代码约定 1 el: 指的是增加直接点的DOM节点 2 totalNum: 为100000(值越大越能

webqq加密js参数分析

以下是分析实例:今天来说说WEBQQ登陆过程的分析,抛砖引玉而已 第一步:使用HttpWatch 软件抓取webQQ页面从打开至登陆成功到所有数据包.我们所有到操作均在这里面查找. 等待抓包中.....  这里为了方便 我已经登陆成功一个号码并且抓包成功. 抓包方法很简单  打开IE  打开HttpWatch 点击记录后 开始一系列的登陆操作直到登陆成功后.停止抓 第二步:我们重新打开一个webqq登陆页面.来分析网页源代码.(这里建议大家使用 Chrome 谷歌浏览器.比较方便.它本身带有一个

WebRTC中的AppRTCDemo.apk简单分析

以前一直在QQ空间记录一些简单的关于webrtc的笔记.博说不如发布CSDN,想想也可以,解决了一些小问题,也可以帮助一下其它碰到该同样问题的人. 上周试着将WebRTC中的PeerConnection_client进行改写,拿 掉了PeerConnection_Server端,改用openfire服务器,信令采用xmpp,主要代码来源于call.主要还是将http请求用xmpp重写了,原理上很简单,合并后,效果还可以. 现在开始看android版本的peerconnection,也就是标题的A