Avant de parler de cette section, passons en revue le morceau de code précédent :
(function (win) { var _$ = function (selector, context) { return new _$.prototype.Init(selector, context); } _$.prototype = { Init: function (selector, context) { this.elements = []; var context = context || document; if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i < arr.length; i++) { this.elements.push(arr[i]); } } ////这一块是选择器的实现,没有写完,可以自己实现 }, each: function (callback) { if (this.elements.length > 0) { for (var i = 0; i < this.elements.length; i++) { callback.call(this, i, this.elements[i]); } } } } _$.prototype.Init.prototype = _$.prototype; window.$ = _$; })(window || global);
Nous avons implémenté la recherche de nœuds ci-dessus. Aujourd'hui, nous allons parler de la liaison d'événements aux nœuds.
Les TX qui connaissent le code source de Jquery devraient le savoir : notre code ci-dessus ne dispose pas de l'événement ready et interroge uniquement les nœuds, sans prendre en compte l'objet document. J'ai déjà parlé de la différence entre window.onload et document.ready, et j'ai également étendu l'événement document.ready.
Maintenant, nous y ajoutons la méthode d'extension :
Notre méthode Init doit être corrigée :
Init: function (selector, context) { this.elements = []; if (typeof selector === "function") { this.elements.push(document); this.ready(selector); } else { var context = context || document; var isDocument = function (ele) { var tostring = Object.prototype.toString; return tostring.call(ele) == "[object HTMLDocument]" || "[object Document]"; } if (isDocument(selector)) { this.elements.push(selector); } else if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i < arr.length; i++) { this.elements.push(arr[i]); } } } }
La signification générale de ce code est la suivante : si le sélecteur de paramètre transmis est de type fonction, exécutez l'événement ready. S'il s'agit d'un document, insérez l'objet document dans le tableau this.elements (une fois transmis, il sera jugé dans l'événement ready). S'il s'agit d'une canalisation de caractères, interrogez simplement le nœud et insérez-le dans le tableau this.elements dans une boucle. Ce n'est pas difficile. Considérez principalement les méthodes d'écriture des deux événements prêts, $(document).ready et $(function(){}).
Nous ajouterons ensuite la fonction ready :
ready: function (callback) { var isDocument = function (ele) { var tostring = Object.prototype.toString; return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]"; } if (isDocument(this.elements[0])) { if (document.addEventListener) { document.addEventListener('DOMContentLoaded', function () { document.removeEventListener('DOMContentLoaded', arguments.callee, false); callback(); }, false); } else if (document.attachEvent) { document.attachEvent('onreadystatechange', function () { if (document.readyState == "complete") { document.detachEvent('onreadystatechange', arguments.callee); callback(); } }); } else if (document.lastChild == document.body) { callback(); } } }
J'ai déjà parlé de ce code (la différence entre onload et ready). Si vous ne le savez pas, vous pouvez y jeter un œil.
Maintenant, nous avons implémenté l'événement ready. Ensuite, vous pouvez enregistrer des événements pour le nœud.
Implémentons la fonction bind, le code est le suivant :
bind: function (type, callback) { if (document.addEventListener) { this.each(function (i, item) { item.addEventListener(type, callback, false); }); } else if (document.attachEvent) { this.each(function (i, item) { item.attachEvent('on' + type, callback); }); } else { this.each(function (i, item) { tem['on' + type] = callback; }); } }
Voici quelques codes de compatibilité pour implémenter l'enregistrement des événements de nœud. Avant chacun, vous ne savez peut-être pas à quoi cela sert. Il est utilisé ici maintenant.
La fonction principale est d'effectuer certaines opérations sur les boucles de nœuds.
Code complet, venez ici :
(function (win) { var _$ = function (selector, context) { return new _$.prototype.Init(selector, context); } _$.prototype = { Init: function (selector, context) { this.elements = []; if (typeof selector === "function") { this.elements.push(document); this.ready(selector); } else { var context = context || document; var isDocument = function (ele) { var tostring = Object.prototype.toString; return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]"; } if (isDocument(selector)) { this.elements.push(selector); } else if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i < arr.length; i++) { this.elements.push(arr[i]); } } } }, each: function (callback) { var length = this.elements.length; if (length > 0) { for (var i = 0; i < length; i++) { callback.call(this, i, this.elements[i]); } } }, ready: function (callback) { var isDocument = function (ele) { var tostring = Object.prototype.toString; return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]"; } if (isDocument(this.elements[0])) { if (document.addEventListener) { document.addEventListener('DOMContentLoaded', function () { document.removeEventListener('DOMContentLoaded', arguments.callee, false); callback(); }, false); } else if (document.attachEvent) { document.attachEvent('onreadystatechange', function () { if (document.readyState == "complete") { document.detachEvent('onreadystatechange', arguments.callee); callback(); } }); } else if (document.lastChild == document.body) { callback(); } } }, bind: function (type, callback) { if (document.addEventListener) { this.each(function (i, item) { item.addEventListener(type, callback, false); }); } else if (document.attachEvent) { this.each(function (i, item) { item.attachEvent('on' + type, callback); }); } else { this.each(function (i, item) { tem['on' + type] = callback; }); } } } _$.prototype.Init.prototype = _$.prototype; window.$ = _$; })(window);
Ces fonctions peuvent essentiellement implémenter l'enregistrement d'événements pour les nœuds. Certains des effets spéciaux restants doivent encore être étendus. Si vous êtes intéressé, vous pouvez ajouter vous-même des méthodes à l’objet _$.prototype.
Ce qui précède représente l’intégralité du contenu de cet article, j’espère qu’il pourra aider tout le monde.