Maison > interface Web > js tutoriel > Le contenu principal du code source de jquery

Le contenu principal du code source de jquery

不言
Libérer: 2018-07-09 15:16:56
original
1355 Les gens l'ont consulté

Cet article présente principalement le contenu de base de jQuery sur l'apprentissage du code source jquery. Il a une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer

Module de base

<.>1. Construction d'objets
// 方法一
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;
    }
}
Copier après la connexion
Il existe deux façons de créer des classes ci-dessus, bien que l'effet final soit cohérent, les performances sont en effet incohérentes lorsque nous instancions trois objets ajquery, pour la première méthode, chacun. L'instance a une méthode sayName, qui gaspille de la mémoire et augmente la surcharge. La deuxième méthode consiste à mettre sayName sur la chaîne de prototypes, afin que chaque objet d'instance puisse partager cette méthode (oui, un bon choix), il suffit de se connecter à la chaîne de prototypes via la portée pour recherche, de sorte qu'il y ait une couche supplémentaire de recherche de chaîne de portée ;

les objets jquery sont considérés en termes de performances, donc juste La chaîne de prototype doit être utilisée

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 = $() ;
Copier après la connexion
2. Séparation de constructeurs d'objets en jquery
Le processus de création d'une nouvelle instance

1. 创建一个空对象
2. 将构造函数的作用域赋给这个对象,这个this就指向了这个对象了
3. 执行构造函数中的代码
4. 返回这个对象
Copier après la connexion
La nouvelle est principalement n'est-ce pas ? La chaîne de prototypes est connectée à celle de l'instance

  • Notre écriture de classe couramment utilisée est la suivante :

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();
Copier après la connexion
  • Si non applicable, un nouveau peut également être implémenté

var $$ = ajquery = function (selector) {
    if(!(this instanceof ajquery)) {
        return new ajquery(selector);
    }
    this.selector = selector;
    return this;
}
Copier après la connexion
  • Écrire en 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
}
Copier après la connexion
init est ajQuery En tant que méthode du constructeur sur le prototype, alors ce n'est pas ajQuery, donc ceci ne peut pas du tout faire référence au prototype d'ajQuery, donc ici la méthode init et ajQuery sont séparés en deux constructeurs indépendants via new.

3. Enchaîner les appels de méthodes
$('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()方法是将最近的筛选操作还原为前一步操作的状态
Copier après la connexion
En regardant la structure de ce code, on peut plus ou moins deviner sa signification :

☑ Connaître le type Input élément de type bouton

☑ Recherchez le premier bouton et liez le gestionnaire d'événements de clic

☑ Revenez à tous les boutons et trouvez le deuxième

☑ comme Lier la fonction de gestionnaire d'événements de clic au deuxième bouton

☑ Liez la fonction de gestionnaire d'événements bascule au troisième bouton

L'idée principale de jquery est d'écrire moins et d'en faire plus.

jquery.fn.init = function() {
    return this;
}

jquery.fn.get = function() {
    return this;
}
Copier après la connexion
// Implémentez les opérations en chaîne en renvoyant this, car renvoyer this de l'instance actuelle vous permet d'accéder à votre propre prototype. Cela économise la quantité de code et améliore l'efficacité du code. Il a l'air plus élégant. Mais il y a un problème avec cette méthode : toutes les méthodes objet renvoient l'objet lui-même, ce qui signifie qu'il n'y a pas de valeur de retour, cette méthode peut donc ne convenir à aucun environnement.

Bien que Javascript soit un langage non bloquant, il ne bloque pas, mais ne peut pas bloquer. Par conséquent, il doit être piloté par des événements et effectuer de manière asynchrone certaines opérations qui doivent bloquer le processus. chaîne synchrone. , en plus du chaînage synchrone, il existe également un chaînage asynchrone jQuery a introduit Promise depuis la version 1.5, et jQuery.Deferred sera discuté plus tard.

4. Conception de l'interface du plug-in
jQUEry fournit deux interfaces pour l'écriture du plug-in, l'une consiste à

le traiter comme une méthode statique et l'autre à suspendre le méthode dans Aller à $.extend() comme méthode de l’objet prototype de jquery. $.fn

fn et jQuery sont en fait deux objets différents. Comme expliqué précédemment : lorsque jQuery.extend est appelé, cela pointe vers l'objet jQuery (jQuery est une fonction et un objet !), donc ici l'extension est dans jQuery. supérieur. Lorsque jQuery.fn.extend est appelé, cela pointe vers l'objet fn, jQuery.fn et jQuery.prototype pointent vers le même objet, et étendre fn consiste à étendre l'objet prototype jQuery.prototype. Ce qui est ajouté ici est la méthode prototype, qui est la méthode objet. Par conséquent, l'API jQuery fournit les deux fonctions d'extension ci-dessus.

5. Développement de plug-ins
Il existe trois modes de développement pour les plug-ins jquery.

  1. $.extend() pour étendre les méthodes statiques jquery

  2. $.fn pour ajouter de nouvelles méthodes d'instance à jquery

  3. $.widget() utilise la méthode widget factory de jquery ui

La première méthode crée simplement une méthode statique sous l'espace de noms de $, qui peut être directement Just utilisez $ pour appeler l'exécution. Il n'est pas nécessaire d'utiliser $('selector') pour sélectionner l'objet DOM puis appeler la méthode.

La troisième méthode est utilisée pour écrire des plug-ins plus avancés et n'est généralement pas utilisée.

La deuxième méthode est la forme la plus couramment utilisée dans notre développement quotidien. Nous étudierons attentivement cette méthode plus tard

$.extend()
$.extend({
    sayName: function(name) {
        console.log(name);
    }
})

$.sayName('meils');
// 直接使用 $.sayName 来调用

// 通过$.extend()向jQuery添加了一个sayHello函数,然后通过$直接调用。到此你可以认为我们已经完成了一个简单的jQuery插件了。
Copier après la connexion
Cette méthode est. utile pour définir certaines méthodes auxiliaires.

$.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...'); //调用
Copier après la connexion
Plug-in de développement $.fn

1 Utilisation de base

$.fn.setColor = function() {
    this.css('color', 'red');
}

//这里的this指向调用我们这个方法的那个对象
Copier après la connexion

2.

Nous pouvons également utiliser notre méthode sur chaque élément de la collection d'éléments que nous avons obtenu.

$.fn.addUrl = function() {
    this.css('css', 'red');
    this.each(function() {
        $(this).append('i');
    })
}
Copier après la connexion

sélectionne une collection, vous pouvez donc jquery选择器 parcourir chaque élément À l'intérieur de $.each(), each` fait référence à chaque élément du DOM, si nécessaire Pour appeler la méthode jquery, vous besoin de l'envelopper avec this; $

3. Appel en chaîne

$.fn.setSelector = function() {
    this.css('color', 'red');
    return this.each(function() {

    })
}
Copier après la connexion

4. Paramètres de réception

我们会使用$.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
    })
}
Copier après la connexion

上面的参数处理有一点不足,我们把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
    })
}
Copier après la connexion

五、面向对象开发插件

你可能需要一个方法的时候就去定义一个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'
});
Copier après la connexion

六、解决命名冲突

因为随着你代码的增多,如果有意无意在全局范围内定义一些变量的话,最后很难维护,也容易跟别人写的代码有冲突。
比如你在代码中向全局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();
}
})();
Copier après la connexion
  • 优化一

var foo=function(){
    //别人的代码
}//注意这里没有用分号结尾

//开始我们的代码。。。
(function(){
    //我们的代码。。
    alert('Hello!');
})();
Copier après la connexion

由于前面的代码没有加;号 , 然后我们的插件加载出错了,所以我们在我们插件的最开始加一个;号来强制前面的结束。

  • 优化二

我们可以将一些系统变量传入我们的插件,这样可以缩短变量的作用域链,将其作为我们插件内部的局部变量来使用,这样可以大大提高我们的速度和性能。

;(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,);
Copier après la connexion

一个安全,结构良好,组织有序的插件编写完成。


六、版本回溯

jquery能过够方便的获取到DOM元素,并且能够遍历它们。你知道这些背后的原理吗?

通过对sizzle的分析,我们知道jquery获取到的是一个jquery对象,是一个包装容器。

Le contenu principal du code source de jquery

你会看到在上面有一个prevObject对象。

在jquery内部维护着一个jquery对象栈,遍历方法每一次遍历都会找到一个新的元素,每一个元素都是一个jquery对象,然后jquery会把这些元素都放到这个栈中。(入栈)

$('ul').find('li');


// 这句话可以拆分,第一个jquery对象是$('ul'); 第二个jquery对象是$('ul').find('li');


// 首先将$('ul')入栈
// 然后将li集合(类数组对象)入栈
Copier après la connexion

因为栈中的每一个元素都是一个jquery对象,每一个jquery对象都有着三个属性,分别时contextselectorprevObject, prevObject 属性就是指向对象栈中的前一个元素的。

这个prevObject 就比较有意思了。它指向前一个元素。

举例子了:

Copier après la connexion
Copier après la connexion
Copier après la connexion
        parent     
  • child
var aaron = $("#aaron");     aaron.find('li').click(function(){         alert(1);     //1     }) // 如果我们想在返回父级 aaron.find('li').click(function(){     alert(1);     //1 }).end().click(function() {     alert(2); }) // end()方法就是进行了回溯,

jquery为我们操纵对象栈提供了两个有用的方法

  • end()

  • addSelf()

这两个方法都是进行版本的回退。

  • end()

返回最近的一次筛选的上一个状态。回到最近的一个"破坏性"操作之前。即,将匹配的元素列表变为前一次的状态。

<p><span>Hello</span>,how are you?</p>

$('p').find('span').end();
// 选取所有的p元素,查找并选取span子元素,然后再回过来选取p元素
Copier après la connexion

end()方法返回的就是一个prevObject;

  • addBank

Copier après la connexion
Copier après la connexion
Copier après la connexion
       
  • list item 1
  •    
  • list item 2
  •    
  • list item 3
  •    
  • list item 4
  •    
  • list item 5
$('li.third-item').nextAll().addBank()                 .css(); // 初始选择位于第3项,初始化堆栈集合只包含这项。调用.nextAll() 后将第4和第5项推入堆栈。最后,调用.addBack() 合并这两个组元素在一起,创建一个jQuery对象,指向所有三个项元素(按照文档中的顺序):{[,
  • ,
  •  ]} // [1] li.third-item 入栈 // [2] 4、5入栈 // [3] addBank 合并重组
    .addBack()方法导致前一组遍历堆栈中的DOM元素被添加到当前组。

    来举例子喽

    // First Example
    $("p.before-addback").find("p").addClass("background");
    // p元素添加背景
    
    // Second Example
    $("p.after-addback").find("p").addBack().addClass("background");
    // 选中的p元素以及前一个元素合并到栈中,全部添加背景
    Copier après la connexion
    利用这个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;
    }
    Copier après la connexion
    • end()源码解析

    jQuery.fn.end = function() {
      return this.prevObject || this.constructor; // 如果存在之前的jquery对象就返回它,如果不存在上一个,就返回当前的jQuery对象。
    }
    Copier après la connexion
    • addBank() 源码解析

    jQuery.fn.addBank = function(selector) {
      return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
    
      // 如果参数为空,就把当前的jquery对象的上一个jQuery对象一起合并为一个新的对象。如果指定了参数,那么就在上一个对象中查找这个对象。
    
    }
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
        
    • 1
    •   
    • 2
    •   
    • 3
    •   
    • 4
    var li = $('ul').find('li'); console.log(li); //结果如下图

    Le contenu principal du code source de jquery

    Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

    Recommandations associées :

    Introduction de base au code source de jquery

  • Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Étiquettes associées:
    source:php.cn
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal