1. Summary of source code idea analysis Summary:
The core idea of jQuery can be simply summarized as "querying and operating dom". Today we will mainly analyze the jQuery.prototype.init selector constructor. Process the parameters in the selector function;
The parameters of this function are the parameters in the execution function of jQuery()===$(). You can first read the article I wrote before about the basic framework of jQuery. After understanding the basic framework, Read this article again.
Idea analysis:
The following are several usage cases of jQuery (used to query dom). Each case returns a selector instance (commonly called a jQuery object (a nodeList object), which contains the queried dom Node):
1. Process $(""), $(null), $(undefined), $(false)
If the parameter is the above illegal value, the jQuery object does not contain the dom node
2. Process $(DOMElement)
If the parameter is a node element, the jQuery object contains the parameter node element, and the attribute values are respectively added as the parameter node element, the context and length attributes of 1 and the usage of using [] to access the dom node in the jQuery object
Example 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. Process $(HTML string)
If the first parameter is an HTML string, the jQuery object contains Childnodes nodes in fragment document fragments created by jQuery.clean function
Example 3.1:
var jqHTML = $('
Article title
Content
');
console.log(jqHTML); // [
,
];
If the first parameter (HTML string) is an empty single tag, and the second parameter context is a non-empty pure object
Example 3.2:
var jqHTML = $('
', { class: 'css-class', data-name: 'data-val' });
console.log(jqHTML.attr['class'] ); //css-class
console.log(jqHTML.attr['data-name']); //data-val
4. Process $(#id)
If the first parameter is a # plus element id, the jQuery object contains the only element node with this id,
and add the context, selector, length attributes and user attributes whose attribute values are document, parameter string, 1, respectively. [] Usage of accessing dom nodes in jQuery objects
Example 4.1:
var jq = $('#container');
console.log(jq.[0]); //Contained dom node elements
console.log(jq.length) ; //1
console.log(jq.context); //document
console.log(jq.selector); //container
5. Process $(.className )
If the first parameter is a .className, the jQuery object has a tag element with the class name className, and adds an attribute value as the parameter string, the document's selector, and the context attribute
The actual execution code is:
return jQuery(document).find(className);
6. Process $(.className, context)
If the first parameter is .className, the second parameter is a context object (can be .className (equivalent to processing $(. className .className)), jQuery object or dom node),
jQuery object contains the descendant node element with class name className in the second parameter context object, and adds a context and selector attributes
The actual execution code is :
return jQuery(context).find(className);
Example 6.1:
html code:
Main content title
Main title
Sub-content title
Subtitle
JavaScript code:
var jq, context;
context = '.sub';
var jq = $('.title', context);
console .log(jq.text()); //Sub-content title
console.log(jq.context); //document
console.log(jq.selector); //.sub .title
context = $('.sub');
var jq = $('.title', context);
console.log(jq.text()); //sub-content title
console .log(jq.context); //document
console.log(jq.selector); //.sub .title
context = $('.sub')[0];
var jq = $('.title', context);
console.log(jq.text()); //Secondary content title
console.log(jq.context); //Node element whose className is sub
console.log(jq.selector); //.title
7. Process $(fn)
If the first parameter is the fn function, call $(document) .ready(fn);
Example 7.1:
$(function(e){
console.log('DOMContent is loaded');
})
//The above code is equivalent to:
jQuery(document).ready(function(e) {
console.log('DOMContent is loaded');
});
8. Process $(jQuery object)
If the first parameter is a jQuery object, It has been analyzed above that if the parameter is a # plus element id when querying the dom, the returned jQuery object will add an attribute value of the parameter string, the document's selector, and the context attribute
Example 8.1:
var jq = $('#container');
console.log( jq.selector); // #container
console.log(jq.context); // document
So what should we do when $($('#container')) appears? ? Similarly, the returned jQuery object is the same as in cases 5 and 6
Example 8.2:
var jq2 = $($('#container'));
console.log(jq2.selector); // #container
console.log(jq2.context ; Code
The code is as follows:
var rootjQuery = $(document),
rquickExpr = /^(?:[^#<]*(<[wW] >)[^>]*$|#([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]为空的单标签元素(如:
)且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 );
}
}
Statement:The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn