本文是对jQuery的发源的先河索求。先经过八个函数来扩展原生DOM的操作,然后引进命名空间以及对其重构,接着将该命名空间扩大到Node上,退换贰个和好的Node二,引出jQuery。

引子

  • 第二,小编有二个须求===========>
    要获得2个<li>标签的全部兄弟成分。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<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>
    <li id="item6">选项6</li>
  </ul>
</body>
</html>

那儿你刚学完原生DOM操作,知道有nextSibling previousSibling parentNode。你意识貌似未有直接一下子获取任何弟兄成分的API啊,身为三个得天独厚的90后,你坚决手写2个函数达成这么些需要啊。

function getSiblings(node){
  var allChild = item2.parentNode.children 
  var childObj = {length: 0}
  for (let i = 0; i < allChild.length; i++){
    if (allChild[i] !== node){
       childObj[childObj.length] = allChild[i]
       childObj.length += 1
    }
  }
  return childObj
}

好了,以上的函数就能满足要求了,它接受你传入的某些成分,重临包罗那么些元素全数兄弟成分的伪数组。

注意: 要用item2.parentNode.children
那规范才不会得到文本节点。所以您想拿到item2的兼具兄弟,只必要getSiblings(item2)

获得全体兄弟的言传身教地址============>demo

  • 您刚化解了三个主题素材,领导又给你提了二个急需,让您给<li>累加五个类

长官还没说完,你立时想到了,直接item2.classList.add('类名')哎呀,哈哈,笔者好聪明啊,不愧是得天独厚的90后。

给您轻易3个要素要一贯抬高这些类名,别给笔者的二个一个的加,太二了,假若成分原来有3个不该存在的类名,给自家删了,领导接着说完全体的急需。

那…看来不能item1.classList.add('类名')
item2.classList.add('类名')
item3.classList.add('类名')诸如此类平庸的干了哟,那我还用函数嘛,你想法。

啊,不愧是拿手思索的90后

function addClass(node, classes){
  for (var key in classes){
    var value = classes[key]
    if (value){
      node.classList.add(key)
    } else{
      node.classList.remove(key)
    }
  }
}

jQuery 1

从未动用办法的时候

上海体育场合是为添新币素的时候的item2的面容,记住它,待会和下图相比。

jQuery 2

施行办法后

能够看到,实施办法后,item2的类名变为b、c,这是因为您是addClass(item2, {a: 0, b: 1, c: true})那般调用的,意思是类名不该有a,删除a,并加上b c


上述对象的遍历并取值用到了falsey

复习一下,js的伍个falsey

  • 0
  • NaN
  • ''
  • null
  • undefined
  • false

除此而外,其余的全是true。


可是你想的太美了,领导察看你的代码中的那个部分,直接抓狂了……

if (value){
      node.classList.add(key)
    } else{
      node.classList.remove(key)
    }
 }

这段代码给本身优化了,明明便是一句话的事。

您回到想了一会,能够如此优化

var methodName = value ? 'add' : 'remove'
node.classList[methodName](key)

最后你把之类代码提交。

function addClass(node, classes){
  for (var key in classes){
    var value = classes[key]
    var methodName = value ? 'add' : 'remove'
    node.classList[methodName](key)
  }
}
  • 只顾一点上述代码不可能用点运算符,要用[]运算符,classList['add'] === classList.add

给任一成分增多类名==========================>demo

取名空间

您做到了下面的八个供给后,领导本着训练你的尺度,又给您提了新的要求。

  • 少林那,你看你那两函数写的挺好的,假使分开放,每一回还要在找,不比放到一同把。
  • 自己擦嘞,让小编放到一同。行吗……
  • 归来后,少林狼狈周章,突然想起了明晚刚去的天坛西街的米粮川超级市场的送货车
  • 自己把那俩函数当成二种商品,笔者开个超级市场,把它俩收起来呗。

var shaolinDom = {} //少林开的超市
shaolinDom.addClass = addClass //把addClass这个商品收进来
shaolin.getSibling = getSiblings //把getSiblings这个商品收进来

那作者咋用吧,该咋用就咋用呗。

shaolinDom.addClass(item5, {a: true, b: false, c: 0}) //把item5上原本的b c类名删掉,加上 a类名
shaolinDom.getSiblings(item6) //获得item6的所有兄弟元素

jQuery 3

命名空间

  • 望着方面包车型大巴代码,笔者就在想啊,照旧要好由优化一下吗,免得回来改。

var shaolinDom = {}
shaolinDom.addClass = function(node, classes){
  for (var key in classes){
    var value = classes[key]
    var methodName = value ? 'add':'remove'
    node.classList[methodName](key)
  }

}

shaolinDom.getSiblings = function (node){
  var allChild = node.parentNode.children
  var childObj = {length: 0}
  for (let i = 0; i< allChild.length; i++){
    if (allChild[i] !== node){
      childObj[childObj.length] = allChild[i]
      childObj.length += 1
    }
  }
  return childObj
}

shaolinDom.addClass(item5, {a: true, b: false, c: 0})
var allSiblings = shaolinDom.getSiblings(item6)
console.log(allSiblings)

引进命名空间=======================>demo

命名空间的优化=====================>demo

  • 您提交了新的须要后,领导对您另眼相待啊,二零一九年的新职工也许不错的
  • 您刚想松口气,领导接着说,少林那,你看你那两函数啊只还好shaolinDom用啊,而且笔者每一回要把item5传到函数里面,每一次好辛勤的啦,你改革一下,让本人的要素得以一贯调用方法呗,比如item5.getSiblings()这么多好。那规范操作的话,item5有着自主权,就好像您买东西,你想去买越发东西你就去买那多少个东西嘛,而不是事物去挑选你呀。
  • 本人擦擦嘞,想想首席营业官分析依然很有道理的,果然还是要一连优化啊……
  • 回来会,作者在工位上想,你不是要操作DOM吗,还想这么item5.getSiblings()操作,那自身此番直接给你干到Node的原型上

Node.prototype.addClass = function(classes){
  for (var key in classes){
    var value = classes[key]
    var methodName = value ? 'add':'remove'
    this.classList[methodName](key)
  }

}

Node.prototype.getSiblings = function (){
  var allChild = this.parentNode.children
  var childObj = {length: 0}
  for (let i = 0; i< allChild.length; i++){
    if (allChild[i] !== this){
      childObj[childObj.length] = allChild[i]
      childObj.length += 1
    }
  }
  return childObj
}
  • 丫的,小编写出那些代码之后,小编须臾间以为本人两米了吗,赶紧去找领导
  • 管事人一看,吸了一口冷气,心想,挺牛 啊,但是作者要问问作者那小子
    this的知识
  • 少林那,你那函数里面this是吗,再给自身讲讲咋用呗
  • 本身屮艸芔茻,轮到笔者牛了吧,笔者把袖子已撸,是这么回事,巴拉巴拉
  • 自然,作者要先给总监讲一下怎么用

item5.addClass({a: true, b: false, c: 0}) //既然Node原型都有了这两函数,item5是node类型,直接用呗
console.log(item6.getSiblings())
  • 本身刚写完,领导就叫,那addClass函数里面那就二个参数啊,getSiblings函数怎么没参数啊
  • 啊,那几个啊,我讲了this后就领会了。不过讲这么些this事先先要讲1讲这些call(),方便理解

//上面的代码等同于以下代码
item5.addClass.call(item5, {a: true, b: false, c: 0}) //call()方法的第一个参数就是this
console.log(item6.getSiblings.call(item6))
  • 假定你把call()省了,直接用()去调用函数,自身脑补call()就好啊,自然也就领会this是什么人啊。
  • 这小子还足以啊,不错。可是要一而再引导一下呀

进一步晋级,绑定Node的原型链上==================>demo
call()便宜清楚this================================>demo

祥和写一个构造函数

没多久,领导的报考大学生又来了

  • 少林那,你看您上次呢你协调写的函数绑到Node上了,看似挺好,然而其余人不自然用你的那两函数啊,你绑到Node上,多占地啊。你自个儿写一个大局函数实现一下相同的必要呢。
  • 嘿,此番经理说的很对呀,笔者的错,笔者创新一下
  • 蓦地联想到从前的各类构造函数,String() Number() Array()能够直接回到一个指标,笔者也这么干啊

window.Node2 = function(node){
  return {
    getSiblings: function(){
      var allChild = node.parentNode.children
      var childObj = {length: 0}
      for (let i = 0; i< allChild.length; i++){
        if (allChild[i] !== node){
          childObj[childObj.length] = allChild[i]
          childObj.length += 1
        }
      }
      return childObj
    },

    addClass: function(classes){
      for (var key in classes){
        var value = classes[key]
        var methodName = value ? 'add':'remove'
        node.classList[methodName](key) //闭包的使用
      }
    }
  }
}
  • 落到实处了1个大局构造函数,再次来到三个对象,该对象里面有五个key,value分别又是三个函数(又体现了函数是第3公墓的地位),而且还用到了闭包。

var node2 = Node2(item3) //node2就是用Node2()构造函数构造的返回的对象
node2.getSiblings() //对象的点运算符去去操作属性啊
node2.addClass({'a': 0, 'b': true, 'c': true})
  • 企管者一看,嗯,是时候让他见识真正的jQuery

投机完结1个构造函数去驾驭=======================>demo

jQuery的雏形

  • 这一次领导没再提供给,而是自己改起了代码

window.jQuery = function(node){
  return {
    getSiblings: function(){
      var allChild = node.parentNode.children
      var childObj = {length: 0}
      for (let i = 0; i< allChild.length; i++){
        if (allChild[i] !== node){
          childObj[childObj.length] = allChild[i]
          childObj.length += 1
        }
      }
      return childObj
    },

    addClass: function(classes){
      for (var key in classes){
        var value = classes[key]
        var methodName = value ? 'add':'remove'
        node.classList[methodName](key) //闭包的使用
      }
    }
  }
}
  • 您看看本人改了叁个职位,你瞧着那像吗
  • 自我看了壹会那难道说是风传中的jQuery
  • 那是它的雏形,大概意思你早已一步一步写出来了,jQuey正是三个构造函数,它回到3个指标,这一个指标有不少key,对应的value又是部分函数。
  • 那怎么还用$那么些操作呢
  • 哈哈,二个语法糖吗,你看

window.$ = jQuery
  • 给您出个题吗,你用现时的学识用jQuery兑现把某部成分变红,最棒证美赞臣下,你的参数是node照旧贰个选取器,提醒一下,能够用querySelector()querySelector会回去文书档案中相配钦点的挑三拣4器组的率先个要素
  • 本人想了一会,写出如下代码

window.JQuery = function(nodeOrSelector){
  let node
  //判断一下nodeOrSelector是node还是一个选择器
  if(typeof nodeOrSelector === 'string'){
    node = document.querySelector(nodeOrSelector)
  } else{
    node = nodeOrSelector
  }

  return {  
    getSiblings: function(){
      var allChild = node.parentNode.children
      var childObj = {length: 0}
      for (let i = 0; i< allChild.length; i++){
        if (allChild[i] !== node){
          childObj[childObj.length] = allChild[i]
          childObj.length += 1
        }
      }
      return childObj
    },

    addClass: function(classes){
      for (var key in classes){
        var value = classes[key]
        var methodName = value ? 'add':'remove'
        node.classList[methodName](key)
      }
    }
  }
}

所以

//var node2 = JQuery('#item3')与下列代码作用相同,把item3变红
var node2 = JQuery('ul > li:nth-child(3)')

jQuery 4

变红啦

jQuery的雏形======================>demo

运用一下和谐的jQuery

  • 少林那,你也会用初级的jQuery了,大家演练一下,你把修改一下全部的<li>的始末吧,能够运用querySelectorAll() 返回一个NodeList的伪数组
  • 本身听完事后,思索了1会,写下了如下代码

window.JQuery = function(nodeOrSelector){
  let nodes = {}
  if(typeof nodeOrSelector === 'string'){
    let temp = document.querySelectorAll(nodeOrSelector) //NodeList
    for (let i = 0; i < temp.length; i++){
      nodes[i] = temp[i]
    }
    nodes.length = temp.length
  } 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)
      }
    })

  }

  //等同于get、set方法
  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
}

调整四个<li>的内容================================>demo

聊起底,少林在经营的教导有方下,开端研讨jQuery的征途。尽管使用量在减低,不过依然有五分之三的web开荒职员在用。

如上并不是一点一滴真实的jQuery的推理,只是大概是十二分意思,能够协理笔者越来越好的驾驭而已。真正的JQuery必须去看文书档案,英文文书档案中文文档

jQuery我来啦~

相关文章

网站地图xml地图