jQuery的重要性不必多讲,对于刚接触js,特别是刚学习完DOM模型的人需要了解的是为什么要学习jQuery呢,jQuery的本质是什么,它与DOM模型的关系是什么? 自己动手封装一个jQuery构造函数可以解决这些问题。
有些时候,需要我们用DOM的API封装一些函数 举一个最简单的例子,我们现在想封装这样一个函数,可以接受一个节点或者一组节点,或者一个选择器作为参数,并且给它加上一个class。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function addClass(nodesOrSelector,className){ if (typeof nodesOrSelector === "string") { //如果参数是字符串的话,代表是一个选择器 var nodes = document.querySelectorAll(nodesOrSelector) for (let i = 0; i < nodesOrSelector.length; i++) { nodes[i].classList.add(className) } } else if (nodesOrSelector instanceof Node) { //如果参数是一个node节点 nodesOrSelector.classList.add(className) } else if (nodesOrSelector instanceof NodeList || nodesOrSelector instanceof HTMLAllCollection) { //如果参数是一个节点集合,nodeList或HTMLCollection for (let i = 0; i < nodesOrSelector.length; i++) { nodesOrSelector[i].classList.add(className) } } }
放到命名空间中 封装完之后我们决定优化一下,这是我们创造的工具呀,放在全局作用域里面可不好,为什么不放到我们的命名空间里面呢1 2 window.qikke = {} qikke.addClass = function(){...}
放到Node的prototype中 放到命名空间之后发现调用的时候有一点奇怪1 qikke.addClass('ul > li','red')
我们想要的效果是这样的
所以我们大胆的吧addClass这个函数放到了Node.prototype中1 Node.prototype.addClass = function(){...}
于是一个接一个的工具函数被放到了Node的原型中。。。时不时的还会被覆盖掉几个。。。
写一个jQuery构造函数 所以我们下决心要自己写一个构造函数1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 window.jQuery = function (nodesOrSelector) { var nodes = {} if (typeof nodesOrSelector === "string") { //如果参数是字符串的话,代表是一个选择器 //querySelectorAll返回一个nodeList 会从nodeList继承很多方法,过滤掉。 var temp = document.querySelectorAll(nodesOrSelector) for (let i = 0; i < temp.length; i++) { nodes[i] = temp[i] } nodes['length'] = temp.length } else if (nodesOrSelector instanceof Node) { //参数是一个node节点,把它构造成一个伪数组 nodes = { 0: nodesOrSelector, length: 1 } } else if (nodesOrSelector instanceof NodeList || nodesOrSelector instanceof HTMLAllCollection) { //参数是一个节点集合,nodeList或HTMLCollection for (let i = 0; i < nodesOrSelector.length; i++) { nodes[i] = nodesOrSelector[i] } nodes['length'] = nodesOrSelector.length } //给nodes对象增加addClass方法 nodes.addClass = function(className){ //为nodes中的节点增加一个class for(let i = 0; i < nodes.length; i++){ nodes[i].classList.add(className) } } //返回构造好的jQuery对象 return nodes } var $div = jQuery('li') $div.addClass('red')
总结
jQuery是一个构造函数,它可以包装普通的DOM对象,然后获得jQuery.prototype中的方法。
而包装后的对象$div失去了与Node对象的联系,所以不能调用Node中的方法了。