jQuery入门

jQuery入门

什么是jQuery

  首先,什么是jQuery?jQuery中文文档的定义是jQuery是一个高效、精简且功能丰富的JavaScript工具库,除去一些修饰语,那它就是一个工具库。库是什么?库是特定种类的API。我们知道函数的封装是为了消除冗余代码,如果有一堆函数实现的功能有某种内在的联系,比如说都是对元素的操作,那我们是不是可以把它们放到同一个地方,与其他函数区分开来?这就形成了一个库。
  让我们先抛开jQuery的定义,来写一个工具库。
  DOM并没有提供获取所有兄弟姐妹元素的API,所以我们来写一个API,让它能获取到某个元素的兄弟姐妹并返回一个伪数组。

function getSiblings(node){  //传入一个节点,获取这个节点的兄弟姐妹
  var temp = node.parentElement.children
  var array = {length: 0}
  for(let i = 0; i < temp.length; i++){
    if(temp[i] !== node){
      array[array.length] = temp[i]  //由于伪数组没有push方法,所以我们直接用对象属性赋值来实现
      array.length++
    }
  }
  return array  //返回这个存了兄弟姐妹的伪数组
}

  DOM只提供了classList.add和classList.remove进行类的添加和删除,但如果我们要同时添加多个类的话这个方法就显得很笨重了,所以我们再写一个关于元素类的API,方便我们对其进行批量添加和删除。

function addClass(node, classes) { //classes传入的是一个对象,key为要添加/删除的类名,value为true/falsefor (var key in classes) {
    classes[key]? node.classList.add(key): node.classList.remove(key)
    /*
    * 当然那一句有点长如果你看着不舒服可以换一种写法:
      var methodName = classes[key]?'add':'remove'
      node.classList[methodName](key)
    *
    */
  }
}

  喏,现在我们有了两个函数,这两个函数都是对节点的操作,但是它们现在看上去毫无关系,所以怎么样可以让别人一眼看出来这两个是同一类型的东西呢?放到同一个命名空间下。

window.cydom = {}
cydom.getSiblings = getSiblings
cydom.addClass = addClass

  这样把它们都放到cydom下,看上去就比较好辨认了。并且我们可以通过cydom.getSiblings来调用getSiblings。
  我们调用它用的是cydom.getSiblings(node)cydom.addClass(node,{'red': true}),如你所见,所有的方法都必定要传一个参数node。所以可不可以变成node.getSiblings()这种形式呢?不知道你们记不记得(1).toString()?是的,把这个方法放到它的原型链上。我们要操作的是节点,所以应该把这两个方法放在Node.prototype里边。也就是如下形式。函数内部使用node参数的时候用this代替。

Node.prototype.getSiblings = function(){...}
Node.prototype.addClass = function(){...}

  但是这样不够安全。怎么说不够安全呢?如果另外有人写了一个函数和这个功能不同,但是取了相同的名字,那么你的这个函数就会被覆盖,或者你可能覆盖别人的函数。所以呢?更好的方法当然是封装了。把这些利用DOM实现的但是比DOM好用的方法用一个构造函数(Node2)封装起来,这样我们通过这个构造函数构造出来的对象就可以直接调用这些方法了。

window.Node2 = function(node) {    //接收一个元素,返回一个新的对象,这个对象有着新的API
  return {  //把这两个方法放到一个hash里边返回
    getSiblings: function() {
      var temp = node.parentElement.children
      var array = {
        length: 0
      }
      for (let i = 0; i < temp.length; i++) {
        if (temp[i] !== this) {
          array[array.length] = temp[i]
          array.length++
        }
      }
      return array
    },
    addClass: function(classes) {
      for (var key in classes) {
        var methodName = classes[key] ? 'add' : 'remove'
        node.classList[methodName](key)
      }
    }
  }
}
//调用
var newnode = Node2(oldnode)
newnode.getSiblings()

  当然,jQuery做到的不只是传入一个元素,还可以传入一个选择器。在前边做个小判断就好了。

window.jQuery = function(nodeOrSelector){
  var node
  if(typeof nodeOrSelector === 'string'){
    node = document.querySelector(nodeOrSelector) 
  }else{
    node = nodeOrSelector
  }
  ...
}

  那如果我们想同时操作多个节点呢?把node变成伪数组nodes。

window.jQuery = function(nodeOrSelector) {
  var nodes = {}
  if (typeof nodeOrSelector === 'string') {
    nodes = document.querySelectorAll(nodeOrSelector)
  } else if (nodeOrSelector instanceof Node) {
    nodes = {
      0: nodeOrSelector,
      length: 1
    }
  }
  return {  //或者可以return nodes,把addClass挂到nodes下,即nodes.addClass = function(){}
    addClass: function(classes) {
      for (var key in classes) {
        let methodName = classes[key] ? 'add' : 'remove'
        for (let i = 0; i < nodes.length; i++) {
          nodes[i].classList[methodName](key)
        }
      }
    }
  }
}

  jQuery还可以通过判断实现多态,比如我们想要实现一个text函数,当它没有参数的时候获取textContent,有参数的话设置textContent。像这样

nodes.text = function(text) { //设置和获取文字
    if (text === undefined) {//不传参数的话默认是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
      }
    }
  }

  好了,让我们回到刚开始的问题,什么是jQuery?jQuery实际上就是一个构造函数,它接受一个参数(可以是元素也可以是选择器),然后返回一个对象来操作节点。

jQuery next

  jQuery就这么简单?不是的。除了DOM操作外,它还有动画、AJAX等模块,功能更加丰富。它使用了prototype,我们这里没有提到。并且它的兼容性很好。
  不过,知道了什么是jQuery之后算是入门了,我们就可以直接看jQuery API了。
  以及,我们经常看到的$就是这里的jQuery,只需要设置window.$ = jQuery即可。还有一个习俗:如果一个对象是由jQuery构造出来的,那就在这个对象前边加上$,让我们知道这个对象是由jQuery构造出来的,这样我们可以用jQuery的API而不是DOM的API。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值