zoukankan      html  css  js  c++  java
  • jQuery源码学习(2):选择器初窥

    选择器初窥

    代码架构:

    jQuery选择器可以依照传入数据的类型分为五大类:

    • 传入字符串:$("div"), $("#id"), $(".div1"),$(".div p.title")
    • 传入html代码:$("<div></div>"), $("<div>1</div><div>2</div>")
    • 传入对象:$(document), $(this)
    • 传入数组或对象字面量:$({}), $([])
    • 传入函数:$(function(){})

    下面我们来看一下jQuery构造函数代码(jQuery-2.2.2第2832行起)的架构:

    jQuery.fn.init = function(selector, context){
      if(!selector){
    
        // part1.处理$(null), $(undefined), $(false), $("")
    
      }
      if(typeof selector == "string"){   
    
        // part2.匹配selector并将结果传入match中 
    
      }
        if(match && (match[1] || !context)){
    
          // part3.创建标签或按#id查询
    
    
        }else{
    
          // part4.处理复杂选择器
    
        }
      }
      // 一些其他的不常见情况
      else {...}
      return jQuery.makeArray(selector, this);
    }

    可以发现jQ将代码依照selector的类型分为了几个部分。下面我们来依次分析这几部分的代码。

    第一部分:检测没有传入值的情况

    此段完整代码如下:

    // HANDLE: $(""), $(null), $(undefined), $(false)
    if ( !selector ) {
      return this;
    }

    第二部分:匹配传入的字符串

    此段完整代码如下:

    if ( selector[ 0 ] === "<" &&selector[ selector.length - 1 ] === ">" &&selector.length >= 3 ) {
      // Assume that strings that start and end with <> are HTML and skip the regex check
      match = [ null, selector, null ];
    } else {
      match = rquickExpr.exec( selector );
    }
    // 匹配html标签或#id
    rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]*))$/,

    通过分析rquickExpr正则表达式,我们可以得出在selector分别为以下几种值时返回值match的结构:

    1. selector = "<div>"

    match = [null, "<div>", null]

    2. selector = "<div>content</div>"

    match = [null, "<div>content</div>", null]

    3. selector = "<div></div>content"

    match = ["<div></div>content", "<div></div>", null]

    4. selector = #id

    match = [#id, null, #id]

    第三部分:创建标签或者按#id查询

    传入标签时:

    此段完整代码如下:

    // 如果是html标签
      if ( match[ 1 ] ) {
    // 如果传入的context是jQ对象,将其转换成原生对象
        context = context instanceof jQuery ? context[0] : context;
    
    // 将传入的html字符串转换成节点数组并传入this中
        jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true));
    
    // 如果是$(html, props)的形式,则要设置对应属性或执行方法
        if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
          for (match in context) {
    
    // 若 prop 的某一项是jQ方法
            if (jQuery.isFunction(this[match])) {
              this[match](context[match]);
    
    // 否则设置对应属性
            } else {
              this.attr(match, context[match]);
            }
          }
        }
    
        return this;
      }
    // 匹配单标签
    var rsingleTag = ( /^<([w-]+)s*/?>(?:</1>|)$/ );

    关键位置的语意都已在注释中讲解过了,下面主要介绍一下$.parseHTML和$.merge这两个方法在其中的应用:

    jQuery.parseHTML( data [, context ] [, keepScripts ] )
    • data:需要被转换成节点的字符串
    • context:被转换的节点所存在的上下文。并没有太大用处,默认是document,在需要在iframe中进行操作时,也可以设成contentWindow。
    • keepScripts:布尔值。设置成true时允许将字符串中的<script>部分也转换成节点。
    jQuery.merge(first, second)

    我们经常用$.merge来进行数组的合并。在本例中需要强调的一点是,$.merge被用来将一个数组合并到类数组对象中。就像下面这样:

      var obj = {0: "hello", 1: "pansy", length: 2};
      var arr = ["from", "arr"];
    
      console.log($.merge(obj, arr));   // Object {0: "hello", 1: "pansy", 2: "from", 3: "arr", length: 4}

    传入id时:

    // HANDLE: $(#id)
    else {
      elem = document.getElementById( match[ 2 ] );
    
      // Support: Blackberry 4.6
      // gEBID returns nodes no longer in the document (#6963)
      if ( elem && elem.parentNode ) {
    
        // Inject the element directly into the jQuery object
        this.length = 1;
        this[ 0 ] = elem;
      }
    
      this.context = document;
      this.selector = selector;
      return this;
    }

    第四部分:处理复杂选择器

    // 处理形如$(".class"), $("ul li+p")等等
    if ( !context || context.jquery ) {
      return ( context || root ).find( selector );
    
    // 当传入上下文是原生对象时,调用构造函数返回jQ对象
    } else {
      return this.constructor( context ).find( selector );
    }

    此处复杂选择器全部借助$().find()方法实现,使用了sizzle引擎,我们稍后再进行介绍。

  • 相关阅读:
    mysql数据类型
    Hive Getting Started补充
    Hive安装
    HDFS High Availability Using the Quorum Journal Manager
    用DBContext (EF) 实现通用增删改查的REST方法
    Internet Explorer 10 administration IE10管理
    配置AD RMS及SharePoint 2013 IRM问题解决及相关资源
    SharePoint 2013 首页修改
    Status: Checked in and viewable by authorized users 出现在sharepoint 2013 home 页面
    添加AD RMS role时,提示密码不能被验证The password could not be validated
  • 原文地址:https://www.cnblogs.com/timl525/p/5335149.html
Copyright © 2011-2022 走看看