实现一个 jQuery 的 API

1. 封装函数

html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
<body>
  <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>
</body>
</html>
1.1 getSiblings

1.1.1 获取 item3 所有的兄弟

var allChildren = item3.parentNode.children
var array = { length:0 }
for( let i=0; i<allChildren.length; i++ ){
    if( allChildren[i] !== item3 ){
        array[array.length] = allChildren[i] // 添加到伪数组中,不用array[i]是因为可能会跳过
        array.length += 1
    }  
}
console.log(array)
 // {0: li#item1, 1: li#item2, 2: li#item3, 3: li#item4, 4: li#item5, length: 5}

封装

function getSiblings(node){
  var allChildren = item3.parentNode.children
  var array = { length:0 }
  for( let i=0; i<allChildren.length; i++ ){
    if( allChildren !== item3 ){
        array[array.length] = allChildren[i] 
        array.length += 1
    }  
  }
  return(array)
}
console.log( getSiblings(item3) )
 // {0: li#item1, 1: li#item2, 2: li#item3, 3: li#item4, 4: li#item5, length: 5}

1.1.2 给 item3 添加 calss

var classes = ['a','b','c']
  classes.forEach((value)=>{ item3.classList.add(value)})
// <li id="item3" class="a b c">选项3</li>

另一种方法,既能 add ,也能 remove

var classes = {'a':true, 'b':false, 'c':true}
for(let key in classes){
  var value = classes[key]
  if(value){
    item3.classList.add(key)
  }else{
    item3.classList.remove(key)
  }
}
// <li id="item3" class="a c">选项3</li>

封装

function addClass(node,classes){
  for(let key in classes){
    var value = classes[key]
    if(value){
      node.classList.add(key)
    }else{
      node.classList.remove(key)
    }
  }
}
addClass(item3,{'a':true, 'b':false, 'c':true})
// <li id="item3" class="a c">选项3</li>

// 代码优化 ( 如果出现类似的代码就存在优化的可能 )
function addClass(node,classes){
  for(let key in classes){
    var value = classes[key]
    var methodName = value ? 'add':'remove'
    node.classList[methodName](key)
    }
}

2. 命名空间

window.xxxdom{}
xxxdom.getSiblings = getSiblings
xxxdom.addClass = addClass

xxxdom.getSiblings()
xxxdom.addClass(item3,{'a':true, 'b':false, 'c':true})

命名空间可以让别人知道你的库叫什么名字,但是上面的代码会覆盖之前声明的变量。
调整代码

window.xxxdom{}
xxxdom.getSiblings = function(node){
  var allChildren = node.parentNode.children
  var array = { length:0 }
  for( let i=0; i<allChildren.length; i++ ){
    if( allChildren !== node ){
        array[array.length] = allChildren[i] 
        array.length += 1
    }  
  }
  return(array)
}
xxxdom.addClass = function(node,classes){
      classes.forEach((value)=>{node.classList.add(value)})
}

xxxdom.getSiblings()
xxxdom.addClass(item3,['a','b','c'])
// 声明变量 xxxdom{} 添加getSiblings和addClass属性,这样就不会覆盖变量

3. Nodetype 和 Node2

怎么样能够像下面这样使用

item3.getSiblings()
item3.addClass(item3,['a','b','c'])

方法1
直接改Node的原型(共有属性)

Node.prototype.getSiblings = function(){
  var allChildren = this.parentNode.children
  var array = { length:0 }
  for( let i=0; i<allChildren.length; i++ ){
    if( allChildren !== this ){
        array[array.length] = allChildren[i] 
        array.length += 1
    }  
  }
  return(array)  
}
console.log(item3.getSiblings())
item3.addClass(['a','b','c'])
// {0: li#item1, 1: li#item2, 2: li#item3, 3: li#item4, 4: li#item5, length: 5}
// <li id="item3" class="a b c">选项3</li>

修改原型的话会相互覆盖,所以这个方法不好。

方法2
重新写一个 Node2

window.Node2 = dunction(node){
  return{
    getSiblings:function(){},
    addClass:function(){}
  }
}
var node2 = Node2(item3)
node2.getSiblings()
node2.addClass(['a','b','c'])

修改代码

window.Node2 = function(node){
  return{
    getSiblings:function(){
      var allChildren = node.parentNode.children
      var array = { length:0 }
      for( let i=0; i<allChildren.length; i++ ){
        if( allChildren !== node ){
            array[array.length] = allChildren[i] 
            array.length += 1
        }  
      }
      return(array)  
    },
    addClass:function(classes){
      classes.forEach((value)=>{node.classList.add(value)})
    }
  }
}
var node2 = Node2(item3)
console.log(node2.getSiblings())
node2.addClass(['a','b','c'])
// {0: li#item1, 1: li#item2, 2: li#item3, 3: li#item4, 4: li#item5, length: 5}
// <li id="item3" class="a b c">选项3</li>

把Node2改成jQuery

window.jQuery = function(node){
  return{
    getSiblings:function(){
      var allChildren = node.parentNode.children
      var array = { length:0 }
      for( let i=0; i<allChildren.length; i++ ){
        if( allChildren !== node ){
            array[array.length] = allChildren[i] 
            array.length += 1
        }  
      }
      return(array)  
    },
    addClass:function(classes){
      classes.forEach((value)=>{node.classList.add(value)})
    }
  }
}

jQuery接受一个旧的节点,返回一个新的对象,这个对象就是jQuery对象,它拥有一些新的api 。

window.jQuery = function(nodeOrSelector){
  let node
  if(typeof nodeOrSelector === 'string'){
    node = document.querySelector(nodeOrSelector)
  }else{
    node = nodeOrSelector
  }
  // 判断是字符串还是节点
  return{
    getSiblings:function(){
      var allChildren = node.parentNode.children
      var array = { length:0 }
      for( let i=0; i<allChildren.length; i++ ){
        if( allChildren !== node ){
            array[array.length] = allChildren[i] 
            array.length += 1
        }  
      }
      return(array)  
    },
    addClass:function(classes){
      classes.forEach((value)=>{node.classList.add(value)})
    }
  }
}
var node2 = jQuery('#item3')
console.log(node2.getSiblings())
node2.addClass(['a','b','c'])

操作多节节点

window.jQuery = function(nodeOrSelector){
  let nodes = {}
  if(typeof nodeOrSelector === 'string'){
    let temp = document.querySelectorAll(nodeOrSelector)//伪数组
    for(i=0; i<temp.length; i++){
      nodes[i] = temp[i]
    }
    nodes.length = temp.length // 返回一个纯净的伪数组,原型直接指向Object
  }else if(nodeOrSelector instanceof Node){
    nodes = {0:nodeOrSelector,length:1}//保持一致,返回一个伪数组
  }
  
  nodes.addClass = function(classes){
    classes.forEach((value)=>{
      for(let i=0; i<nodes.length; i++){
        nodes[i].classList.add(value)
      }
    })
  }
  return nodes
}
var node2 = jQuery('ul>li')
node2.addClass(['a','b','c'])
// 给所有的 item 加上相同的 class
// <li id="item1" class="a b c">选项1</li>
// <li id="item2" class="a b c">选项2</li>
// <li id="item3" class="a b c">选项3</li>
// <li id="item4" class="a b c">选项4</li>
// <li id="item5" class="a b c">选项5</li>

获取和修改文本

window.jQuery = function(nodeOrSelector){
  let nodes = {}
  if(typeof nodeOrSelector === 'string'){
    let temp = document.querySelectorAll(nodeOrSelector)//伪数组
    for(i=0; i<temp.length; i++){
      nodes[i] = temp[i]
    }
    nodes.length = temp.length // 返回一个纯净的伪数组,原型直接指向Object
  }else if(nodeOrSelector instanceof Node){
    nodes = {0:nodeOrSelector,length:1}//保持一致,返回一个伪数组
  }
  
  nodes.addClass = function(classes){
    classes.forEach((value)=>{
      for(let i=0; i<nodes.length; i++){
        nodes[i].classList.add(value)
      }
    })
  }
  nodes.getText = function(){
    var texts = []
    for(let i=0; i<nodes.length; i++){
      texts.push(nodes[i].textContent)
    }
    return texts
  }
  nodes.setText = function(text){
    for(let i=0; i<nodes.length; i++ ){
      nodes[i].textContent = text
    }
  }
  return nodes
}
var node2 = jQuery('ul>li')
node2.addClass(['a','b','c'])
node2.setText('hi')

优化

window.jQuery = function(nodeOrSelector){
  let nodes = {}
  if(typeof nodeOrSelector === 'string'){
    let temp = document.querySelectorAll(nodeOrSelector)//伪数组
    for(i=0; i<temp.length; i++){
      nodes[i] = temp[i]
    }
    nodes.length = temp.length // 返回一个纯净的伪数组,原型直接指向Object
  }else if(nodeOrSelector instanceof Node){
    nodes = {0:nodeOrSelector,length:1}//保持一致,返回一个伪数组
  }
  
  nodes.addClass = function(classes){
    classes.forEach((value)=>{
      for(let i=0; i<nodes.length; i++){
        nodes[i].classList.add(value)
      }
    })
  }
//   nodes.getText = function(){
//     var texts = []
//     for(let i=0; i<nodes.length; i++){
//       texts.push(nodes[i].textContent)
//     }
//     return texts
//   }
//   nodes.setText = function(text){
//     for(let i=0; i<nodes.length; i++ ){
//       nodes[i].textContent = text
//     }
//   }
  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 = jQuery('ul>li')
node2.addClass(['a','b','c'])
node2.text('hi')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容