zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    全文检索 部署及使用
    mysql 数据库常见的一些基本操作 !详不详细你说了算!
    Django 语法笔记
    CentOs Linux 对于 修改 yum源 为 阿里
    小白老凯,初出茅庐!请多关照!简单分享一些 mysql 数据库的安装操作!请给为大神雅正!
    sql server 之一条Sql语句引发的悲剧
    翻译高质量JavaScript代码书写基本要点(转载)
    翻编JavaScript有关的10个怪癖和秘密(转载)
    IIS7.5部署ASP.NET失败
    linq to sql报错,
  • 原文地址:https://www.cnblogs.com/lilyimage/p/3785316.html
Copyright © 2011-2022 走看看