19前端成长日记-自己实现一个 jQuery API

158 阅读2分钟

封装函数

// 获取所以兄弟节点
var getSiblings = function(node) {
  var siblings = {
    length: 0
  }
  var childrens = node.parentNode.children
  for (var i = 0; i < childrens.length; i++) {
    if (childrens[i] !== node) {
      siblings[length] = childrens[i]
    }
    length += 1
  }
  return siblings
}
// 添加多个类名
var addClass = function(node, classes) {
  for (var key in classes) {
    var action = classes[key]? 'add': 'remove'
    node.classList[action](key)
  }
}
addClass(item3, {a: true,b: true,c: false})

给封装的函数添加一个命名空间

给函数名前加上前缀 为什么要加命名空间:

  1. 能让别人知道你的库叫什么
  2. 不加命名空间容易覆盖全局变量
window.TqDom = {} 
TqDom.getSiblings = getSiblings
TqDom.addClass = addClass

简化代码

window.TqDom = {}

TqDom.getSiblings = function(node) {
  var siblings = {
    length: 0
  }
  var childrens = node.parentNode.children
  for (var i = 0; i < childrens.length; i++) {
    if (childrens[i] !== node) {
      siblings[length] = childrens[i]
    }
    length += 1
  }
  return siblings
}

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

以上代码用起来很麻烦,每次调用都得使用 TqDom.xxx() 将代码简化 node.xxx()

  1. 给 Node 添加共有属性
Node.prototype.getSiblings = function() {
  var siblings = {
    length: 0
  }
  var childrens = this.parentNode.children
  for (var i = 0; i < childrens.length; i++) {
    if (childrens[i] !== this) {
      siblings[length] = childrens[i]
    }
    length += 1
  }
  return siblings
}

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

但是这种方法不好,容易覆盖别人添加的方法或属性。所以我们自己需要在构造一个 Node

  1. 自己构造 Node
window.Node2 = function(node) {
  return {
    getSiblings: function(node) {
      var siblings = {
        length: 0
      }
      var childrens = node.parentNode.children
      for (var i = 0; i < childrens.length; i++) {
        if (childrens[i] !== node) {
          siblings[length] = childrens[i]
        }
        length += 1
      }
      return siblings
    },
    addClass: function(classes) {
      for (var key in classes) {
        var action = classes[key] ? 'add' : 'remove'
        node.classList[action](key)
      }
    }
  }
}

var node2 = Node2(item3)
node2.addClass({red:true})

上面代码默认传入的参数都是节点,但是如果传入的是选择器呢

window.Node2 = function(nodeOrSelector) {
var node
// 判读传入参数数据类型如果是字符串,就找到对应的节点,
if (typeof nodeOrSelector === 'string'){
    node = document.querySelector(nodeOrSelector)
} else {
    node = nodeOrSelector
}
  return {
    getSiblings: function(node) {
      var siblings = {
        length: 0
      }
      var childrens = node.parentNode.children
      for (var i = 0; i < childrens.length; i++) {
        if (childrens[i] !== node) {
          siblings[length] = childrens[i]
        }
        length += 1
      }
      return siblings
    },
    addClass: function(classes) {
      for (var key in classes) {
        var action = classes[key] ? 'add' : 'remove'
        node.classList[action](key)
      }
    }
  }
  return node
}

最后一步,将 Node 改成自己喜欢的名字

window.TqDom = function(nodeOrSelector) {
var node
// 判读传入参数数据类型如果是字符串,就找到对应的节点,
if (typeof nodeOrSelector === 'string'){
    node = document.querySelector(nodeOrSelector)
} else {
    node = nodeOrSelector
}
  return {
    getSiblings: function(node) {
      var siblings = {
        length: 0
      }
      var childrens = node.parentNode.children
      for (var i = 0; i < childrens.length; i++) {
        if (childrens[i] !== node) {
          siblings[length] = childrens[i]
        }
        length += 1
      }
      return siblings
    },
    addClass: function(classes) {
      for (var key in classes) {
        var action = classes[key] ? 'add' : 'remove'
        node.classList[action](key)
      }
    }
  }
  return node
}

在写个缩写 alias

window.$ = TqDom
//这样在调用我们的函数的时候就只要写$()
var $div = $('div')
$div.addClass()