本文是针对jQuery的来源的初步探索。先经个别独函数来扩张原生DOM的操作,然后引入命名空间和对那个重构,接着用拖欠命名空间扩大至Node上,改造一个自己的Node2,引出jQuery。

引子

  • 首先,我发生一个要求===========>
    要拿走一个<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晚,你坚决手写一个函数实现之需要啊。

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晚。

吃您随便一个因素如直抬高这个类名,别为自己之一个一个之加以,太次了,如果元素原来有一个请勿应是的类名,给本人去了,领导就说了所有底要求。

这…看来不能够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)
    }
  }
}

图片 1

并未以方法的上

达成图是为上加元素的时段的item2的面目,记住它们,待会和下图对比。

图片 2

推行方后

好望,执行方式后,item2的类名变为b、c,这是盖您是addClass(item2, {a: 0, b: 1, c: true})然调用的,意思是类名不应当有a,删除a,并加上b c


如上目标的遍历并取值用到了falsey

习一下,js的6只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的所有兄弟元素

图片 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事先先行使说话同样张嘴是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) //闭包的使用
      }
    }
  }
}
  • 落实了一个大局构造函数,返回一个靶,该目标中有有限独key,value分别又是零星个函数(又映现了函数是第一公墓的位置),而且还因此到了闭包。

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

自己实现一个构造函数去领悟=======================>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即便是一个构造函数,它回到一个目标,这个目标有好多key,对应之value又是有些函数。
  • 那么怎么还用$以此操作也
  • 哈哈,一个语法糖吗,你看

window.$ = jQuery
  • 叫你发出单书写吧,你用今天底文化用jQuery兑现将有元素变红,最好证明一下,你的参数是node还是一个选择器,提示一下,可以用querySelector()querySelector会面返回文档中匹配指定的选器组的首先个要素
  • 自思念了一会,写来如下代码

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)')

图片 4

变红啦

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

行使一下要好之jQuery

  • 少林那,你也会就此初级的jQuery了,咱们练习一下,你将修改一下所有的<li>的情吧,可以采用querySelectorAll() 返回一个NodeList的伪数组
  • 自放任罢以后,思考了一会,写下了之类代码

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的道。虽然使用量在下降,但是还有60%之web开发人员在就此。

如上并无是全然真实的jQuery的推理,只是约是杀意思,可以帮忙我更好的明白而已。真正的JQuery必须去押文档,英文文档,汉语文档

jQuery我来啦~

相关文章

网站地图xml地图