The core content of jquery source code
This article mainly introduces the core content of jQuery about jquery source code learning. It has certain reference value. Now I share it with you. Friends in need can refer to it
Core module
1. Construction of objects
// 方法一 function ajquery (name) { this.name = name; this.sayName = function() { return this.name; } return this; } // 方法二 function ajquery(name) { this.name = name; } ajquery.prototype = { sayName : function () { return this.name; } }
The above are two ways to create classes. Although the final effect is consistent, the performance is indeed inconsistent. When we instantiate three ajquery objects, for Method one, each instance has a sayName method, which wastes memory and increases overhead. Method two is to put sayName on the prototype chain, so that every instance object can share this method (which is a good idea option), just connect to the prototype chain through the scope to search, so that there is an additional layer of scope chain search;
jquery objects are considered in terms of performance, so they must be used Is there a prototype chain?
jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); } jQuery.fn = jQuery.prototype = { init:function(){ return this }, jquery: version, constructor: jQuery, // ……………… } var a = $() ;
2. Separation of object constructors in jquery
The process of new an instance
1. 创建一个空对象 2. 将构造函数的作用域赋给这个对象,这个this就指向了这个对象了 3. 执行构造函数中的代码 4. 返回这个对象
new is mainly about the prototype chain and this of the instance Connect it
Our commonly used class writing method is as follows:
var $$ = ajquery = function (selector) { this.selector = selector; return this; } ajquery.fn = ajquery.prototype = { getSelector: function () { return this.selector; }, constructor: ajquery } var a = new $$('aaa'); a.getSelector();
If new is not applicable, it can also be implemented
var $$ = ajquery = function (selector) { if(!(this instanceof ajquery)) { return new ajquery(selector); } this.selector = selector; return this; }
Writing in jquery
var $$ = ajquery = function(selector) { return new ajquery.fn.init(selector); } ajquery.fn = ajquery.prototype = { name: 'meils', init: function (selector){ console.log(this); }, constructor: ajquery }
init is a method as a constructor on the ajQuery prototype, then this It is no longer ajQuery, so this cannot refer to the prototype of ajQuery at all, so here the init method and ajQuery are separated into two independent constructors through new.
3. Chain calling of methods
$('input[type="button"]') .eq(0).click(function() { alert('点击我!'); }).end().eq(1) .click(function() { $('input[type="button"]:eq(0)').trigger('click'); }).end().eq(2) .toggle(function() { $('.aa').hide('slow'); }, function() { $('.aa').show('slow'); }); // end()方法是将最近的筛选操作还原为前一步操作的状态
Looking at the structure of this code, we can more or less guess its meaning:
☑ Find out the type type is The input element of button
☑ Find the first button and bind the click event handler function
☑ Return to all buttons and find the second one
☑ as the second one Bind the click event processing function to a button
☑ Bind the toggle event processing function to the third button
The core idea of jquery is to write less and do more.
jquery.fn.init = function() { return this; } jquery.fn.get = function() { return this; }
// Implement chain operations by returning this, because by returning this of the current instance, you can access your own prototype. This saves the amount of code, improves the efficiency of the code, and the code looks better. grace. But there is a problem with this method: all object methods return the object itself, which means there is no return value, so this method may not be suitable in any environment.
Although Javascript is a non-blocking language, it does not block, but cannot block. Therefore, it needs to be driven by events and asynchronously complete some operations that need to block the process. This processing is only a synchronous chain. , in addition to synchronous chaining, there is also asynchronous chaining. Asynchronous chaining jQuery has introduced Promise since 1.5, and jQuery.Deferred will be discussed later.
4. Design of plug-in interface
jQUery provides two interfaces for writing plug-ins. One is to $.extend()
process it as a static method. The other is to hang the method on $.fn
as a method of jquery's prototype object.
fn and jQuery are actually two different objects. As explained before: when jQuery.extend is called, this points to the jQuery object (jQuery is a function and an object!), so here the extension is in jQuery superior. When jQuery.fn.extend is called, this points to the fn object, jQuery.fn and jQuery.prototype point to the same object, and extending fn is to extend the jQuery.prototype prototype object. What is added here is the prototype method, which is the object method. Therefore, the jQuery API provides the above two extension functions.
5. Plug-in development
There are three development modes for jquery plug-ins.
$.extend() to extend jquery static methods
$.fn Add new instance methods to jquery
$.widget() uses the widget factory method of jquery ui
The first method just creates a static method under the $ namespace, which can be directly Just use $ to call execution. There is no need to use $('selector') to select the DOM object and then call the method.
The third method is used to write more advanced plug-ins and is generally not used.
The second method is the most commonly used form in our daily development. We will study this method carefully later
$.extend()
$.extend({ sayName: function(name) { console.log(name); } }) $.sayName('meils'); // 直接使用 $.sayName 来调用 // 通过$.extend()向jQuery添加了一个sayHello函数,然后通过$直接调用。到此你可以认为我们已经完成了一个简单的jQuery插件了。
This This method is still useful for defining some auxiliary methods.
$.extend({ log: function(message) { var now = new Date(), y = now.getFullYear(), m = now.getMonth() + 1, //!JavaScript中月分是从0开始的 d = now.getDate(), h = now.getHours(), min = now.getMinutes(), s = now.getSeconds(), time = y + '/' + m + '/' + d + ' ' + h + ':' + min + ':' + s; console.log(time + ' My App: ' + message); } }) $.log('initializing...'); //调用
$.fn Development plug-in
1. Basic usage
$.fn.setColor = function() { this.css('color', 'red'); } //这里的this指向调用我们这个方法的那个对象
2. Each() traversal
We can also use our method on each element of the collection of elements we obtain.
$.fn.addUrl = function() { this.css('css', 'red'); this.each(function() { $(this).append('i'); }) }
jquery selector
selects a collection, so you can $.each()
to traverse each element, inside each
,this
` refers to each DOM element. If you need to call the jquery method, you need to wrap it with $
;
3. Chain call
$.fn.setSelector = function() { this.css('color', 'red'); return this.each(function() { }) }
4. Receiving parameters
我们会使用$.extend()来处理我们参数,因为这个方法如果传入多个参数后,他会把这些合并到第一个上。如果存在有同名参数,那么遵循后面的覆盖前面的。
// 利用这一点,我们可以在插件里定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上,最后就实现了用户指定了值的参数使用指定的值,未指定的参数使用插件默认值。 $.fn.setStyle = function(options) { var default = { color: 'red', fontSize: '15px' } var setting = $.extend(default, optioins); return this.css({ 'color': setting.color, 'fontSize': setting.fontSize }) }
上面的参数处理有一点不足,我们把default也改变了,万一我们接下来还要使用该怎么办呢,所以我们还需要在做修改
$.fn.setStyle = function(options) { var default = { color: 'red', fontSize: '15px' } var setting = $.extend({}, default, optioins); return this.css({ 'color': setting.color, 'fontSize': setting.fontSize }) }
五、面向对象开发插件
你可能需要一个方法的时候就去定义一个function,当需要另外一个方法的时候,再去随便定义一个function,同样,需要一个变量的时候,毫无规则地定义一些散落在代码各处的变量。
还是老问题,不方便维护,也不够清晰。当然,这些问题在代码规模较小时是体现不出来的。
// 如果将需要的重要变量定义到对象的属性上,函数变成对象的方法,当我们需要的时候通过对象来获取,一来方便管理,二来不会影响外部命名空间,因为所有这些变量名还有方法名都是在对象内部。 var beautify = function(ele, option) { this.$element = this.ele; this.default = { 'color': 'red', 'fontSize': '12px', 'textDecoration':'none' } this.ops = $.extend({}, default, option); } beautify.prototype = { setStyle : function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }) // return this对象,实现链式调用 } } $.fn.myPlugin = function(option) { var beautify = new beautify(this, option); beautify.setStyle(); } /// 使用 $('a').myPlugin({ 'color': '#2C9929', 'fontSize': '20px' });
六、解决命名冲突
因为随着你代码的增多,如果有意无意在全局范围内定义一些变量的话,最后很难维护,也容易跟别人写的代码有冲突。
比如你在代码中向全局window对象添加了一个变量status用于存放状态,同时页面中引用了另一个别人写的库,也向全局添加了这样一个同名变量,最后的结果肯定不是你想要的。所以不到万不得已,一般我们不会将变量定义成全局的。
一个最好的方法就是始终使用自调用的匿名函数来包裹你的代码,这样,就可以完全放心的使用自己的变量了。
绝对不会有命名冲突。
;(function() { var beautify = function(ele, option) { this.$element = this.ele; this.default = { 'color': 'red', 'fontSize': '12px', 'textDecoration':'none' } this.ops = $.extend({}, default, option); } beautify.prototype = { setStyle : function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }) // return this对象,实现链式调用 } } $.fn.myPlugin = function(option) { var beautify = new beautify(this, option); beautify.setStyle(); } })();
优化一
var foo=function(){ //别人的代码 }//注意这里没有用分号结尾 //开始我们的代码。。。 (function(){ //我们的代码。。 alert('Hello!'); })();
由于前面的代码没有加;
号 , 然后我们的插件加载出错了,所以我们在我们插件的最开始加一个;
号来强制前面的结束。
优化二
我们可以将一些系统变量传入我们的插件,这样可以缩短变量的作用域链,将其作为我们插件内部的局部变量来使用,这样可以大大提高我们的速度和性能。
;(function($, window, document, undefined) { var beautify = function(ele, option) { this.$element = this.ele; this.default = { 'color': 'red', 'fontSize': '12px', 'textDecoration':'none' } this.ops = $.extend({}, default, option); } beautify.prototype = { setStyle : function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }) // return this对象,实现链式调用 } } $.fn.myPlugin = function(option) { var beautify = new beautify(this, option); beautify.setStyle(); } })(jQuery, window,document,);
一个安全,结构良好,组织有序的插件编写完成。
六、版本回溯
jquery能过够方便的获取到DOM元素,并且能够遍历它们。你知道这些背后的原理吗?
通过对sizzle的分析,我们知道jquery获取到的是一个jquery对象,是一个包装容器。
你会看到在上面有一个prevObject
对象。
在jquery内部维护着一个jquery对象栈,遍历方法每一次遍历都会找到一个新的元素,每一个元素都是一个jquery对象,然后jquery会把这些元素都放到这个栈中。(入栈)
$('ul').find('li'); // 这句话可以拆分,第一个jquery对象是$('ul'); 第二个jquery对象是$('ul').find('li'); // 首先将$('ul')入栈 // 然后将li集合(类数组对象)入栈
因为栈中的每一个元素都是一个jquery对象,每一个jquery对象都有着三个属性,分别时context
、selector
、prevObject
, prevObject
属性就是指向对象栈中的前一个元素的。
这个prevObject
就比较有意思了。它指向前一个元素。
举例子了:
-
parent
- child
jquery为我们操纵对象栈提供了两个有用的方法
end()
addSelf()
这两个方法都是进行版本的回退。
end()
返回最近的一次筛选的上一个状态。回到最近的一个"破坏性"操作之前。即,将匹配的元素列表变为前一次的状态。
<p><span>Hello</span>,how are you?</p> $('p').find('span').end(); // 选取所有的p元素,查找并选取span子元素,然后再回过来选取p元素
end()
方法返回的就是一个prevObject
;
addBank
- list item 1
- list item 2
- list item 3
- list item 4
- list item 5
.addBack()方法导致前一组遍历堆栈中的DOM元素被添加到当前组。
来举例子喽
// First Example $("p.before-addback").find("p").addClass("background"); // p元素添加背景 // Second Example $("p.after-addback").find("p").addBack().addClass("background"); // 选中的p元素以及前一个元素合并到栈中,全部添加背景
利用这个DOM元素栈可以减少重复的查询和遍历的操作,而减少重复操作也正是优化jQuery代码性能的关键所在。
在对对象栈的操作中,用到了一个pushStack()
pushStack 生成了一个新 jQuery 对象 ret,ret 的 prevObject 属性是指向调用 pushStack 函数的那个 jQuery 对象的,这样就形成了一个栈链,其它原型方法如 find、nextAll、filter 等都可以调用 pushStack 函数,返回一个新的 jQuery 对象并维持对象栈。
jQuery.fn.pushStack = function (elems) { // 将 elems 合并到 jQuery 对象中 var ret = jQuery.merge(this.constructor(), elems); // 实现对象栈 ret.prevObject = this; // 返回 return ret; }
end()源码解析
jQuery.fn.end = function() { return this.prevObject || this.constructor; // 如果存在之前的jquery对象就返回它,如果不存在上一个,就返回当前的jQuery对象。 }
addBank() 源码解析
jQuery.fn.addBank = function(selector) { return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector)); // 如果参数为空,就把当前的jquery对象的上一个jQuery对象一起合并为一个新的对象。如果指定了参数,那么就在上一个对象中查找这个对象。 }
- 1
- 2
- 3
- 4
The above is the entire content of this article. I hope it will be helpful to everyone's study. For more related content, please pay attention to the PHP Chinese website!
Related recommendations:
The above is the detailed content of The core content of jquery source code. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Detailed explanation of jQuery reference method: Quick start guide jQuery is a popular JavaScript library that is widely used in website development. It simplifies JavaScript programming and provides developers with rich functions and features. This article will introduce jQuery's reference method in detail and provide specific code examples to help readers get started quickly. Introducing jQuery First, we need to introduce the jQuery library into the HTML file. It can be introduced through a CDN link or downloaded

How to use PUT request method in jQuery? In jQuery, the method of sending a PUT request is similar to sending other types of requests, but you need to pay attention to some details and parameter settings. PUT requests are typically used to update resources, such as updating data in a database or updating files on the server. The following is a specific code example using the PUT request method in jQuery. First, make sure you include the jQuery library file, then you can send a PUT request via: $.ajax({u

jQuery is a fast, small, feature-rich JavaScript library widely used in front-end development. Since its release in 2006, jQuery has become one of the tools of choice for many developers, but in practical applications, it also has some advantages and disadvantages. This article will deeply analyze the advantages and disadvantages of jQuery and illustrate it with specific code examples. Advantages: 1. Concise syntax jQuery's syntax design is concise and clear, which can greatly improve the readability and writing efficiency of the code. for example,

How to remove the height attribute of an element with jQuery? In front-end development, we often encounter the need to manipulate the height attributes of elements. Sometimes, we may need to dynamically change the height of an element, and sometimes we need to remove the height attribute of an element. This article will introduce how to use jQuery to remove the height attribute of an element and provide specific code examples. Before using jQuery to operate the height attribute, we first need to understand the height attribute in CSS. The height attribute is used to set the height of an element

Title: jQuery Tips: Quickly modify the text of all a tags on the page In web development, we often need to modify and operate elements on the page. When using jQuery, sometimes you need to modify the text content of all a tags in the page at once, which can save time and energy. The following will introduce how to use jQuery to quickly modify the text of all a tags on the page, and give specific code examples. First, we need to introduce the jQuery library file and ensure that the following code is introduced into the page: <

Title: Use jQuery to modify the text content of all a tags. jQuery is a popular JavaScript library that is widely used to handle DOM operations. In web development, we often encounter the need to modify the text content of the link tag (a tag) on the page. This article will explain how to use jQuery to achieve this goal, and provide specific code examples. First, we need to introduce the jQuery library into the page. Add the following code in the HTML file:

jQuery is a popular JavaScript library that is widely used to handle DOM manipulation and event handling in web pages. In jQuery, the eq() method is used to select elements at a specified index position. The specific usage and application scenarios are as follows. In jQuery, the eq() method selects the element at a specified index position. Index positions start counting from 0, i.e. the index of the first element is 0, the index of the second element is 1, and so on. The syntax of the eq() method is as follows: $("s

How to tell if a jQuery element has a specific attribute? When using jQuery to operate DOM elements, you often encounter situations where you need to determine whether an element has a specific attribute. In this case, we can easily implement this function with the help of the methods provided by jQuery. The following will introduce two commonly used methods to determine whether a jQuery element has specific attributes, and attach specific code examples. Method 1: Use the attr() method and typeof operator // to determine whether the element has a specific attribute
