<strong id="riedb"><track id="riedb"></track></strong><em id="riedb"><acronym id="riedb"></acronym></em>
<tbody id="riedb"></tbody>
  • <em id="riedb"><acronym id="riedb"></acronym></em>
    <tbody id="riedb"></tbody>

  • <tbody id="riedb"><center id="riedb"></center></tbody>
  • 首頁 > 編程 > JavaScript > 正文

    jQuery.prototype.init選擇器構造函數源碼思路分析

    2019-11-20 23:00:23
    字體:
    來源:轉載
    供稿:網友
    一、源碼思路分析總結
    概要:
    jQuery的核心思想可以簡單概括為“查詢和操作dom”,今天主要是分析一下jQuery.prototype.init選擇器構造函數,處理選擇器函數中的參數;
    這個函數的參數就是jQuery()===$()執行函數中的參數,可以先看我之前寫的淺析jQuery基礎框架一文,了解基礎框架后,再看此文。
    思路分析:
    以下是幾種jQuery的使用情況(用于查詢dom),每種情況都返回一個選擇器實例(習慣稱jQuery對象(一個nodeList對象),該對象包含查詢的dom節點):
    1、處理 $(""), $(null), $(undefined), $(false)
    如果參數為以上非法值,jQuery對象不包含dom節點
    2、處理 $(DOMElement)
    如果參數為節點元素,jQuery對象包含該參數節點元素,并分別增加屬性值為參數節點元素、1的context、length屬性和用[]訪問jQuery對象中dom節點的用法
    例2.1:
    復制代碼 代碼如下:

    var obj = document.getElementById('container'),
    jq = $(obj);

    console.log(jq.length); //1
    console.log(jq.context); //obj
    console.log(jq.[0]); //obj

    3、處理$(HTML字符串)
    如果第一個參數為HTML字符串,jQuery對象包含由jQuery.clean函數創建的fragment文檔碎片中的childnodes節點
    例3.1:
    復制代碼 代碼如下:

    var jqHTML = $('<h1>文章標題</h1><p>內容</p>');
    console.log(jqHTML); //[<h1>,<p>];

    如果第一個參數(HTML字符串)為一個空的單標簽,且第二個參數context為一個非空純對象
    例3.2:
    復制代碼 代碼如下:

    var jqHTML = $('<div></div>', { class: 'css-class', data-name: 'data-val' });

    console.log(jqHTML.attr['class']); //css-class
    console.log(jqHTML.attr['data-name']); //data-val

    4、處理$(#id)
    如果第一個參數是一個#加元素id,jQuery對象包含唯一擁有該id的元素節點,
    并分別增加屬性值為document、參數字符串、1、的context、selector、length屬性和用[]訪問jQuery對象中dom節點的用法
    例4.1:
    復制代碼 代碼如下:

    var jq = $('#container');

    console.log(jq.[0]); //包含的dom節點元素
    console.log(jq.length); //1
    console.log(jq.context); //document
    console.log(jq.selector); //container

    5、處理$(.className)
    如果第一個參數是一個.className,jQuery對象中擁有class名為className的標簽元素,并增加一個屬性值為參數字符串、document的selector、context屬性
    實際執行代碼為:
    復制代碼 代碼如下:

    return jQuery(document).find(className);

    6、處理$(.className, context)
    如果第一個參數是.className,第二個參數是一個上下文對象(可以是.className(等同于處理$(.className .className)),jQuery對象或dom節點),
    jQuery對象包含第二個參數上下文對象中擁有class名為className的后代節點元素,并增加一個context和selector屬性
    實際執行代碼為:
    復制代碼 代碼如下:

    return jQuery(context).find(className);

    例6.1:
    html代碼:
    復制代碼 代碼如下:

    <div class="main">
    <h2 class="title">主內容標題</h2>
    <p>主標題</p>
    </div>
    <div class="sub">
    <h2 class="title">次內容標題</h2>
    <p>次標題</p>
    </div>

    JavaScript代碼:
    復制代碼 代碼如下:

    var jq, context;
    context = '.sub';
    var jq = $('.title', context);
    console.log(jq.text()); //次內容標題
    console.log(jq.context); //document
    console.log(jq.selector); //.sub .title
    context = $('.sub');
    var jq = $('.title', context);
    console.log(jq.text()); //次內容標題
    console.log(jq.context); //document
    console.log(jq.selector); //.sub .title
    context = $('.sub')[0];
    var jq = $('.title', context);
    console.log(jq.text()); //次內容標題
    console.log(jq.context); //className為sub的節點元素
    console.log(jq.selector); //.title

    7、處理$(fn)
    如果第一個參數是fn函數,則調用$(document).ready(fn);
    例7.1:
    復制代碼 代碼如下:

    $(function(e){
    console.log('DOMContent is loaded');
    })
    //上面代碼等同于:
    jQuery(document).ready(function(e) {
    console.log('DOMContent is loaded');
    });

    8、處理$(jQuery對象)
    如果第一個參數是jQuery對象,上面已經分析過如果在查詢dom時,參數是一個#加元素id,返回的jQuery對象會增加一個屬性值為參數字符串、document的selector、context屬性
    例8.1:
    復制代碼 代碼如下:

    var jq = $('#container');
    console.log(jq.selector); // #container
    console.log(jq.context); // document

    那么當出現$($('#container'))該如何處理呢?同樣的,返回的jQuery對象同情況5和6處理的情況一樣
    例8.2:
    復制代碼 代碼如下:

    var jq2 = $($('#container'));
    console.log(jq2.selector); // #container
    console.log(jq2.context); // document

    二、源碼注釋分析
    [ 基于jQuery1.8.3 ]
    復制代碼 代碼如下:

    var rootjQuery = $(document),
    rquickExpr = /^(?:[^#<]*(<[/w/W]+>)[^>]*$|#([/w/-]*)$)/;
    jQuery.fn = jQuery.prototype = {
    init: function( selector, context, rootjQuery ) {
    var match, elem, ret, doc;
    // Handle $(""), $(null), $(undefined), $(false)
    if ( !selector ) {
    return this;
    }
    // Handle $(DOMElement)
    if ( selector.nodeType ) {
    this.context = this[0] = selector;
    this.length = 1;
    return this;
    }
    // Handle HTML strings
    if ( typeof selector === "string" ) {
    if ( selector.charAt(0) === "<" && selector.charAt( 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 );
    }
    // Match html or make sure no context is specified for #id
    // match[1]不為null,則為html字符串,match[2]不為null,則為元素id
    if ( match && (match[1] || !context) ) {
    // HANDLE: $(html) -> $(array)
    if ( match[1] ) {
    context = context instanceof jQuery ? context[0] : context;
    doc = ( context && context.nodeType ? context.ownerDocument || context : document );
    // scripts is true for back-compat
    // selector是由文檔碎片中的childnodes組成的數組
    selector = jQuery.parseHTML( match[1], doc, true );
    // 如果match[1]為空的單標簽元素(如:<div><div>)且context為對象字面量
    if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
    // 如果context對象不為空,則將對象中的屬性添加到selector數組中僅有的dom節點中
    this.attr.call( selector, context, true );
    }
    // merge函數的參數應該為兩個數組,目的是將第二個數組中的項合并到第一個數組,而this并不是一個數組,
    // this是選擇器init構造函數的實例對象,該對象繼承jQuery.prototype對象中的length屬性(默認為0),因此可以理解好merge函數源碼
    // 將selector中的dom項合并到this對象中,并返回該對象
    return jQuery.merge( this, selector );
    // HANDLE: $(#id)
    } else {
    elem = document.getElementById( match[2] );
    // Check parentNode to catch when Blackberry 4.6 returns
    // nodes that are no longer in the document #6963
    if ( elem && elem.parentNode ) {
    // Handle the case where IE and Opera return items
    // by name instead of ID
    // ie6,7和Opera存在此bug,當一個標簽name和一個標簽id值相等時,
    // document.getElementById(#id)函數將返回提前出現的標簽元素
    if ( elem.id !== match[2] ) {
    // 如果存在以上Bug,則返回由find函數返回的document文檔的后代元素集合
    return rootjQuery.find( selector );
    }
    // Otherwise, we inject the element directly into the jQuery object
    this.length = 1;
    this[0] = elem;
    }
    this.context = document;
    this.selector = selector;
    return this;
    }
    // HANDLE: $(expr, $(...))
    // context不存在或者context為jQuery對象
    } else if ( !context || context.jquery ) {
    return ( context || rootjQuery ).find( selector );
    // HANDLE: $(expr, context)
    // (which is just equivalent to: $(context).find(expr)
    // context為className或者dom節點元素
    } else {
    // 等同于jQuery(context).find(selector)
    return this.constructor( context ).find( selector );
    }
    // 處理$(fn)===$(document).ready(fn)
    } else if ( jQuery.isFunction( selector ) ) {
    return rootjQuery.ready( selector );
    }
    // 處理$(jQuery對象)
    if ( selector.selector !== undefined ) {
    this.selector = selector.selector;
    this.context = selector.context;
    }
    // 當第一個參數selector為jQuery對象時,將selector中的dom節點合并到this對象中,并返回this對象
    return jQuery.makeArray( selector, this );
    }
    }
    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    黄色片自拍视频网站在线观看不卡无码丨精品精品自在现拍国产2021丨亚洲三级片在线观看在线免费观看丨波多野结衣在线视频一区二区三区
    <strong id="riedb"><track id="riedb"></track></strong><em id="riedb"><acronym id="riedb"></acronym></em>
    <tbody id="riedb"></tbody>
  • <em id="riedb"><acronym id="riedb"></acronym></em>
    <tbody id="riedb"></tbody>

  • <tbody id="riedb"><center id="riedb"></center></tbody>