实现一个jquery api

2019-06-20  本文已影响0人  lyp82nkl

jQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。jQuery设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。
jQuery的核心特性可以总结为:具有独特的链式语法和短小清晰的多功能接口;具有高效灵活的css选择器,并且可对CSS选择器进行扩展;拥有便捷的插件扩展机制和丰富的插件。

jQuery本质

Query实质上是一个构造函数,该构造函数接受一个参数,jQuery通过这个参数利用原生API找到节点,之后返回一个方法对象,该方法对象上的方法对节点进行操作(方法使用了闭包)。

封装函数

<ul>
  <li id="item1">选项1</li>
  <li id="item2">选项2</li>
  <li id="item3">选项3</li>
  <li id="item4">选项4</li>
  <li id="item5">选项5</li>
</ul>
1. 获取某一标签的全部兄弟元素
function getSiblings(node){
  var allChildren = node.parentNode.children;
  var arr = {
    length: 0
  }; //声明一个伪数组
for(var i =0;i<allChildren.length;i++){
   if(allChildren[i] !== node){
     arr[arr.length] = allChildren[i];
     arr.length += 1;
   }
}
return arr;
}
2. 给一个标签添加多个class
function addClass(node,classes){
  for(var key in classes){
    var value = classes[key];
    if(value){
      node.classList.add(key);
    }else{
      node.classList.remove(key)
    }
  }
}

以上两个函数,我们就可以直接对它们传参进行操作:

//得到除item2的全部兄弟元素
console.log(getSiblings(item2))
//给item2添加a,c两个类
addClass(item2,{a:true,b:false,c:true})

命名空间

我们获得了两个函数:getSiblings() , addClass() ,他们都是操纵节点,那我们能把他们联系起来吗?所以我们可以把他们放到一个库里,给它命名,这就叫命名空间。

window.ldom = {}
ldom.getSiblings(node)
ldom.addClass(node,classes)
 var ldom = {}//声明一个名字为ldom的空间
ldom.getSiblings = function(node){
  var allChildren = node.parentNode.children;
 
  var arr = {
    length: 0
  };
for(var i =0;i<allChildren.length;i++){
  if(allChildren[i] !== node){
    arr[arr.length] = allChildren[i];
    arr.length += 1;
  }
}
return arr;
}
ldom.addClass = function(node,classes){
  for(var key in classes){
    var value = classes[key];
    var method =value ? 'add' : 'remove';
    node.classList[method](key);
  }
}
console.log(ldom.getSiblings(item3));
ldom.addClass(item3,{a:true,b:false,c:true})

将 node 放在前面

node.getSiblings()
node.addClass()
方法一:扩展 Node 接口

直接在 Node.prototype 上加函数

Node.prototype.getSiblings=function(){
  //this就是Node构造函数的实例对象,也就是节点
  var allChildren = this.parentNode.children;
  var arr = {
    length: 0
  };
for(var i =0;i<allChildren.length;i++){
  if(allChildren[i] !== this){
    arr[arr.length] = allChildren[i]; 
    arr.length += 1;
  }
}
return arr;
}
Node.prototype.addClass = function(classes){
  for(var key in classes){
    var value = classes[key];
    var method =value ? 'add' : 'remove';
   this.classList[method](key);
  }
}
console.log(item3.getSiblings.call(item3))  //item3就是节点也就是Node的实例对象,它的下划线原型指向Node.prototype
item3.addClass.call(item3,{a:true,b:false,c:true})
方法二:创建一个新的接口函数
window.Node2 = function(nodesSelect){
  let nodes = {};
  if(typeof nodesSelect === 'string'){
    let temp = document.querySelectorAll(nodesSelect);//利用一个新的中间变量的到一个干净的伪数组(下划线原型直接执行Object)
    for(let i =0;i<temp.length;i++){
      nodes[i]= temp[i]
    }
    nodes.length = temp.length;  }else if(nodesSelect instanceof Node){
    nodes = {   //这里之所以写成一个伪数组,是为了下面遍历它
      0: nodesSelect,
      length: 1
    }
  }
 
  nodes.addClass = function(classes){
    classes.forEach((value)=>{
      for(let i = 0;i<nodes.length;i++){
        nodes[i].classList.add(value)
      }
    })
  }
 
//设置和获取文本内容
nodes.text = function(text){
    if(text === undefined){
      var texts = [];
      for(let i =0;i<nodes.length;i++){
        texts.push(nodes[i].textContent)
      }
      return texts;
    }else{
      for(let i =0;i<nodes.length;i++){
        nodes[i].textContent = text;
      }
    }
  }
  return nodes;
}
var node2 = Node2(item3);
node2.addClass(['blue'])

将Node2 改个名字

function jQuery(node){
    return {
        element: node,
        getSiblings: function(){

        },
        addClass: function(){

        }
    }
}
let node =document.getElementById('x')
let node2 =jQuery(node)
node2.getSiblings()
node2.addClass()

再给个缩写 alias

window.$ = jQuery

//$=jQuery也是可以的

这时就可以直接通过$('item2')来调用了,也就达到了类型jquery的效果

DOM对象跟jQuery对象相互转换

jQuery对象转换成DOM对象:

DOM对象转换成jQuery对象:
上一篇下一篇

猜你喜欢

热点阅读