分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

jQuery源码解析(jQuery对象的实例属性和方法)

发布时间:2023-09-06 02:19责任编辑:苏小强关键词:jQuery

1、记录版本号 以及 修正constructor指向

 ??jquery: core_version, ??constructor: jQuery,

  因为jQuery.prototype={ ... } 这种写法将自动生成的jQuery.prototype.constructor属性覆盖删除,所以需要重新修正(指向其构造函数 jQuery)。
2、init() 初始化方法:

     init()方法最终返回的是this -jQuery(其实是jQuery.prototype.init)方法的实例对象。

     实例对象继承了jQuery的实例属性和方法,且具有下标为0、1、2...、length的属性,从而 css()等方法可以利用 for...in循环处理 $() 集合中DOM元素。火狐下控制台截图如下:

下面分步骤分析代码:

      ①if:传入无效的参数selector,直接返回this。

 ???init: function( selector, context, rootjQuery ) { ????????????var match, elem; ????if ( !selector ) { ????????return this; ????}; ????????... ????}

  ②if :传入的参数selector是字符串, rquickExpr是前面声明的变量:rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;

          else if :传入的是DOM元素;

          else if: 传入的是函数,调用$("document").ready(function(){ ... });

          if :传入的是jQuery对象(存在属性selector);

init: function( selector, context, rootjQuery ) { ???????... ????if ( typeof selector === "string" ) { ???????if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {           ?match = [ null, selector, null ];        } else {       ??  ?match = rquickExpr.exec( selector );          ???????}; ??????... ?????}else if ( selector.nodeType ) {            this.context = this[0] = selector;            this.length = 1;            return this;        } else if ( jQuery.isFunction( selector ) ) {            return rootjQuery.ready( selector );        }        if ( selector.selector !== undefined ) {            this.selector = selector.selector;            this.context = selector.context;        }        return jQuery.makeArray( selector, this ); };

上面代码中,if :情况包括类似 $("<div></div>")、$("<div>aaa</div><div>aaa</div>") 两中情况;
                     else :包括其余情况,例如:$(“</div>111”)、$("#id")、$(".class")、$("div")、$("#id .class div")等情况。requickExpr匹配的是$(“</div>111”)、$("#id")两种情况。如果传入的是$(“</div>111”),则match=["</div>111","</div>",null];如果传入的是$("#id"),则match=["#id",null,“id”];

         ③ 接下来是if esle 判断

         if :match不为null 且 match[1]不为null(传入的是标签形式),或match不为null且content为null(传入的是id形式,无需制定上下文);

         else if:  如果context没有传入或者传入是$()对象形式,则调用$().find ;

         else:如果context传入是原生jsDom对象形式,则调用$().find

if ( match && (match[1] || !context) ) { ??????}else if ( !context || context.jquery ) { ????????return ( context || rootjQuery ).find( selector );}else { ???????????????return this.constructor( context ).find( selector );}

     ④match不为null时,又分标签形式 和 id形式

     涉及到的函数:$.parseHTML 、$.merge、$.isPlainObject()

     $.parseHTML :将字符串转换为存储DOM节点的数组 。第一个参数为传入的字符串,第二个为指定的根节点,第三个是boolean值 (“<script></script>”是否可以转化为<script>标签),默认为false,不转换。

     $.merge:合并两个数组,在jQuery内部不仅可以合并数组,也可以合并类数组。例如:

var ?a={0:"aaa",1:"bbb",length:2} , ????b=["ccc","ddd"];$.merge(a,b); ??//{0:"aaa",1:"bbb",2:"ccc",3:"ddd",length:4};

        jQuery源码中先利用$.parseHTML 将传入的标签字符串转化为DOM节点数组,然后利用$.merge将DOM数组扩充到jQuery对象。
       $.isPlainObject():判断传入的参数是否是由 {}或new Object 创建的对象。

   代码分析:

   if:标签形式,(创建DOM并扩充到jQuery对象)

    if ( match[1] ) { ???????//传入的第二个参数如果是jQuery对象,则转化为原生DOM        context = context instanceof jQuery ? context[0] : context;        //利用merge对jQuery实例对象进行扩充        jQuery.merge( this, jQuery.parseHTML(            match[1],            context && context.nodeType ? context.ownerDocument || context : document,            true        ) );        ...    } else {        ...    }

  if:传入的第一个参数 是单标签字符串 且 第二个参数是纯对象 ,例如 $("<div>",{"html":"aaa","title":"aaa"});

  对第二个对象进行for in 循环,如果jQuery[match]是函数,调用jQuery[match](context[match]); 否则调用jQuery.attr(match,context[match])

if ( match[1] ) { ???... ???if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { ?????for ( match in context ) { ????????if ( jQuery.isFunction( this[ match ] ) ) { ????????????this[ match ]( context[ match ] ); ????????} else { ???????????this.attr( match, context[ match ] ); ???????} ???} ???} ???return this;} else { ????...}

else:传入的是#id 形式

if ( match[1] ) { ??...} else { ???elem = document.getElementById( match[2] );    if ( elem && elem.parentNode ) {        this.length = 1;        this[0] = elem;    }     this.context = document;    this.selector = selector;    return this;}

相关jQuery源码:

jQuery.fn = jQuery.prototype = { ???// The current version of jQuery being used ???jquery: core_version, ????constructor: jQuery, ???init: function( selector, context, rootjQuery ) { ???????var match, elem; ????????// HANDLE: $(""), $(null), $(undefined), $(false) ???????if ( !selector ) { ???????????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 ???????????if ( match && (match[1] || !context) ) { ????????????????// HANDLE: $(html) -> $(array) ???????????????if ( match[1] ) { ???????????????????context = context instanceof jQuery ? context[0] : context; ????????????????????// scripts is true for back-compat ???????????????????jQuery.merge( this, jQuery.parseHTML( ???????????????????????match[1], ???????????????????????context && context.nodeType ? context.ownerDocument || context : document, ???????????????????????true ???????????????????) ); ????????????????????// HANDLE: $(html, props) ???????????????????if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { ???????????????????????for ( match in context ) { ???????????????????????????// Properties of context are called as methods if possible ???????????????????????????if ( jQuery.isFunction( this[ match ] ) ) { ???????????????????????????????this[ match ]( context[ match ] ); ????????????????????????????// ...and otherwise set as attributes ???????????????????????????} else { ???????????????????????????????this.attr( match, context[ match ] ); ???????????????????????????} ???????????????????????} ???????????????????} ????????????????????return this; ????????????????// 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 ) { ???????????????????????// Inject the element directly into the jQuery object ???????????????????????this.length = 1; ???????????????????????this[0] = elem; ???????????????????} ????????????????????this.context = document; ???????????????????this.selector = selector; ???????????????????return this; ???????????????} ????????????// HANDLE: $(expr, $(...)) ???????????} else if ( !context || context.jquery ) { ???????????????return ( context || rootjQuery ).find( selector ); ????????????// HANDLE: $(expr, context) ???????????// (which is just equivalent to: $(context).find(expr) ???????????} else { ???????????????return this.constructor( context ).find( selector ); ???????????} ????????// HANDLE: $(DOMElement) ???????} else if ( selector.nodeType ) { ???????????this.context = this[0] = selector; ???????????this.length = 1; ???????????return this; ????????// HANDLE: $(function) ???????// Shortcut for document ready ???????} else if ( jQuery.isFunction( selector ) ) { ???????????return rootjQuery.ready( selector ); ???????} ????????if ( selector.selector !== undefined ) { ???????????this.selector = selector.selector; ???????????this.context = selector.context; ???????} ????????return jQuery.makeArray( selector, this ); ???}, ????// Start with an empty selector ???selector: "", ????// The default length of a jQuery object is 0 ???length: 0, ??????? ...};

jQuery源码解析(jQuery对象的实例属性和方法)

原文地址:https://www.cnblogs.com/ZheOnaAndOnly/p/9824347.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved