经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » jQuery » 查看文章
jQuery 源码分析(二) 入口模块
来源:cnblogs  作者:大沙漠  时间:2019/8/26 9:09:28  对本文有异议

jQuery返回的对象本质上是一个JavaScript对象,而入口模块则可以保存对应的节点的引用,然后供其它模块操作

我们创建jQuery对象时可以给jQuery传递各种不同的选择器,如下:

  false        ;返回一个空jQuery对象

  DOM节点      ;返回包含该DOM元素引用的jQuery对象。

  body        ;字符串'body',返回包含body元素引用的jQuery对象

  单独标签      ;调用document.createElement创建标签对应的DOM元素

  较复杂的html代码  ;调用jQuery.buildFragment创建元素

  函数        ;是$(document).ready(function)的简写,等到DOM加载完毕后再执行,后面有几篇专门介绍

例如:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
  7. </head>
  8. <body>
  9. <p id="p">123</p>
  10. <script>
  11. console.log( $(false) )
  12. console.log( $(p) )
  13. console.log( $('body') )
  14. console.log( $('<p>123</p>') )
  15. $(function(){console.log('Dom loaded')})
  16. </script>
  17. </body>
  18. </html>

输出如下:

输出的五条信息分别对应上面的五个输出,第一条为空jQuery对象,第二条为包含p元素的jQuery对象,第三条为包含body节点引用的jQuery对象,第四条为jQuery创建的未挂载到dom的jQuery对象,第五条就直接输出信息的,对应着例子的$(function(){})对象

 

 源码分析


 writer by:大沙漠 QQ:22969969

 入口模块就是上一篇文章分析的jQuery内部的jQuery.fn.init函数,该函数会通过参数的不同来做不同的实现,如下:

  1. init: function( selector, context, rootjQuery ) { //负责解析参数selector和context的类型,并执行相应的逻辑
  2. var match, elem, ret, doc;
  3. // Handle $(""), $(null), or $(undefined)
  4. if ( !selector ) { //selector是"",null,undefined和false的等可以转换为false的情况下,对应上面的第一个jQuery实例
  5. return this;
  6. }
  7. // Handle $(DOMElement)
  8. if ( selector.nodeType ) { //selector有属性nodeType,则认为selector是DOM元素,例如:$(document.getELementById('d'))对应上面的第二个jQuery实例
  9. this.context = this[0] = selector;
  10. this.length = 1;
  11. return this;
  12. }
  13. // The body element only exists once, optimize finding it
  14. if ( selector === "body" && !context && document.body ) { //如果参数selector是字符串'body',且context为空,如:$('body'),对应上面的第三个jQuery实例
  15. this.context = document;
  16. this[0] = document.body;
  17. this.selector = selector;
  18. this.length = 1;
  19. return this;
  20. }
  21. // Handle HTML strings
  22. if ( typeof selector === "string" ) { //参数selector是字符串形式
  23. // Are we dealing with HTML string or an ID?
  24. if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { //如果参数selector以"<"开头、以">"结尾,且长度大于等于3
  25. // Assume that strings that start and end with <> are HTML and skip the regex check
  26. match = [ null, selector, null ]; //则假设这个字符串是HTML片段,跳过正则quickExpr的检查。注意这里仅仅是假设,并不一定表示它是真正合法的HTML代码
  27. } else {
  28. match = quickExpr.exec( selector ); //否则用quickExpr来检测参数selector是否为稍微复杂一点的代码,
  29. }
  30. // Verify a match, and that no context was specified for #id
  31. if ( match && (match[1] || !context) ) {
  32. // HANDLE: $(html) -> $(array)
  33. if ( match[1] ) {
  34. context = context instanceof jQuery ? context[0] : context;
  35. doc = ( context ? context.ownerDocument || context : document );
  36. // If a single string is passed in and it's a single tag
  37. // just do a createElement and skip the rest
  38. ret = rsingleTag.exec( selector );
  39. if ( ret ) { //如果参数selector是单独标签比如$('<p></p>');
  40. if ( jQuery.isPlainObject( context ) ) {
  41. selector = [ document.createElement( ret[1] ) ];
  42. jQuery.fn.attr.call( selector, context, true );
  43. } else {
  44. selector = [ doc.createElement( ret[1] ) ];
  45. }
  46. } else {
  47. ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
  48. selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
  49. }
  50. return jQuery.merge( this, selector );
  51. // HANDLE: $("#id")
  52. } else { //参数selector是"#id"格式,如:$('#p1')
  53. elem = document.getElementById( match[2] );
  54. // Check parentNode to catch when Blackberry 4.6 returns
  55. // nodes that are no longer in the document #6963
  56. if ( elem && elem.parentNode ) {
  57. // Handle the case where IE and Opera return items
  58. // by name instead of ID
  59. if ( elem.id !== match[2] ) {
  60. return rootjQuery.find( selector );
  61. }
  62. // Otherwise, we inject the element directly into the jQuery object
  63. this.length = 1;
  64. this[0] = elem;
  65. }
  66. this.context = document;
  67. this.selector = selector;
  68. return this;
  69. }
  70. // HANDLE: $(expr, $(...))
  71. } else if ( !context || context.jquery ) {
  72. return ( context || rootjQuery ).find( selector );
  73. // HANDLE: $(expr, context)
  74. // (which is just equivalent to: $(context).find(expr)
  75. } else {
  76. return this.constructor( context ).find( selector );
  77. }
  78. // HANDLE: $(function)
  79. // Shortcut for document ready
  80. } else if ( jQuery.isFunction( selector ) ) { //如果参数selector是函数,则认为是绑定ready事件,从这里可以看出$(function) 是$(document).ready(function)的简写,这里对应上面的第五个jQuery实例
  81. return rootjQuery.ready( selector );
  82. }
  83. if ( selector.selector !== undefined ) {
  84. this.selector = selector.selector;
  85. this.context = selector.context;
  86. }
  87. return jQuery.makeArray( selector, this );
  88. },

这样jQuery实例就获取到了对应的DOM节点的引用,之后就可以用底层模块或功能模块进行操作了。

 

原文链接:http://www.cnblogs.com/greatdesert/p/11399137.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号