菜鸟朱茱霞的前端搬砖史

自制jQuery

2018-05-07  本文已影响19人  朱珠霞

自己做一个jQuery的思路


封装两个函数 → 添加命名空间 → 扩展Node原型/无侵入设置

<!--html代码-->
<body>
  <h1>text</h1>
  <ul>
    <li id="item1">选项1</li>
    <li id="item2">选项2</li>
    <li id="item3">选项3</li>
    </ul>
</body>
1、封装两个函数
//javaScript代码
function getSiblings(node) {
  var allChlidren = node.parentNode.chlidren
  var array = { 
    length:0 
  }
  for(let i=0;i<allChildren.length;i++){
    if(allChildren[i] !== node){
    array[array.length] =allChildren[i]
    array.length += 1
    }
  }
  return array
}
//调用方法
getSiblings(item2)
//javaScript代码
function addClass(node,classes){
  for (let key in classes){
    var value = classes[key]
    var methodName = value? ' add ' : ' remove ' 
    node.classList[methodName](key)
  }
}
// 调用addClass()
addClass(item1,{ a:ture , b:false} )

//语法基础
classList[methodName === classList.methodName

2、添加命名空间
//javaScrip代码
window.textdom = {} // yui
textdom.getSiblings=function (node) {
  var allChlidren = node.parentNode.chlidren
  var array = { 
    length:0 
  }
  for(let i=0;i<allChildren.length;i++){
    if(allChildren[i] !== node){
    array[array.length] =allChildren[i]
    array.length += 1
    }
  }
  return array
}
textdom.addClass = function (node,classes){
  for (let key in classes){
    var value = classes[key]
    var methodName = value? ' add ' : ' remove ' 
    node.classList[methodName](key)
  }
}
//调用方法
textdom.getSiblings( item3 )
textdom.addClass ( item3,{a:false , b:true } )

了解不扎实的语法基础: for in 语法

3、 扩展Node原型/无侵入设置

上面的函数调用方法都是textdom.addClass()这样的,假如设想,直接以目标元素为对象进行方法调用,如item2.getClass('red'),方法有两种。

Node.prototype.getSiblings =function ( ) {
  var allChlidren = this.parentNode.chlidren
  var array = { length:0 }
  for(let i=0;i<allChildren.length;i++){
    if(allChildren[i] !== this){
      array[array.length] =allChildren[i]
      array.length += 1
     }
  }
  return array
}
Node.prototype.addClass = function(classes){
  classes.forEach( 
    ( value ) => this.classList.add( value ) 
  )
}
//调用函数:
item3.getSiblings.call(items) 
//等价于item3.getSiblings()
item3.addClass.call( item1,[ 'text' , 'red' , 'blue' ] )
//等价于item3.addClass( ['text' , 'red' , 'blue' ] )

① this知识点 : this是call()的第一个参数
② 箭头函数
③函数调用: f.call ( asThis , input1 , input2 )
其中asThis会被当作this,[ input1 , input2 ]会被当作arguments

第一版 基本实现直接目标元素调用的目的

//javaScript
window.Node2 =  function( node ){
  return{
    getSiblings : function( ){
      var allChlidren = this.parentNode.chlidren
      var array = { length:0 }
      for(let i=0;i<allChildren.length;i++){
        if(allChildren[i] !== this){
          array[array.length] =allChildren[i]
          array.length += 1
        }
      }
      return array
    },
    addClass : function (classes ) {
      classes.forEach( 
        (value) => this.classList.add(value) 
      )
    } 
  }
}
var item3 = Node2(item3)
//实现调用
item3.getSiblings()
item3.addClass([ ' red ' ])

console.dir(node2) //得到的是一个原型为Object.prototype,里面含有addClass()等方法的对象

第二版 可以使用选择器确定目标元素

window.Node2 =  function( nodeOrSelector ){
  let node
  if(typeof nodeOrSelector === 'string' ){
    node= document.querySelector(nodeOrSelector)
  }else{
    node= nodeOrSelector
  }
  return{
    getSiblings : function(){
      var allChlidren =node.parentNode.chlidren
      var array = { length:0 }
      for(let i=0;i<allChildren.length;i++){
        if(allChildren[i] !==node){
        array[array.length] =al lChildren[i]
        array.length += 1
        }
      }
      return array
    },
    addClass : function (classes ) {
      classes.forEach( 
        (value) =>node.classList.add(value)
      )
    } 
  }
}
var item3= Node2(item3)

使用了闭包

第三版 可以实现对多个目标元素设置

window.Node2 =  function( nodeOrSelector ){
    let nodes = { }
    if( typeof nodeOrSelector === 'string' ){
        let temp =  document.querySelectorALL ( nodeOrSelector)
        for(let i=0 ; i<temp.length ; i++ ){
            nodes[i] = temp[i]
        }
        node.length = i //得到一个伪数组
    }else if (nodeOrSelector instanceof Node){
        nodes = {
        0:nodeSelector , 
        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)
    }
    nodes.setText = function (text){
        for ( let i=0 ; i<nodes.length ; i++ ){
            nodes[ i ] .textContext = text
        }
    }
    return nodes
}

了解jQuery的一些特点


<div id=x></div>
var div = document.getElementById('x');
var $div = $('#x');
请说出 div 和 $div 的联系和区别。

联系:
$div = $( div ) 可以将div变成$div
div = $div [0]div = $div.get(0)可以将$div变成div
区别:
div 是一个DOM(element)对象,它的原型是node.prototype
$div是由jQuery函数构建的数组对象,它的原型是jQuery.prototype,他的属性和方法有0 1 2.....length selector 等等

上一篇 下一篇

猜你喜欢

热点阅读