先造两个小轮子
我们先造两个函数, 用来简化我们DOM操作
获取所有兄弟节点
function getSiblings(node) {
let target = node.parentNode.children
let siblings = {length:0}
for(let i=0; i
批量增加删除class
function addClass(node, classes) {
for(key in classes) {
if(classes[key]) {
node.classList.add(key)
}else {
node.classList.remove(key)
}
}
}
在我们写代码的时候, 如果出现类似的代码, 就有优化的可能
上面第二个例子, 我们发现if里面的两句很像, 我们考虑下能不能优化下呢
if(classes[key]) {
node.classList.add(key)
}else {
node.classList.remove(key)
我们可以优化为
let methodName = classes[key] ? 'add' : 'remove'
node.classList[methodName](key)
优化后的代码
function addClass(node, classes) {
for(let key in classes) {
let methodName = classes[key] ? 'add' : 'remove'
node.classList[methodName](key)
}
}
命名空间
接下来把两个函数包装下, 让别人知道他俩是一个家族的, 都是用来操作DOM的, 这里为了简单化, 就不用原型链或者类的方法来写了
window.ssdom = {}
ssdom.getSiblings = getSiblings
ssdom.addClass = addClass
上面这种给函数加个前缀的方法就是命名空间
这样我们就可以继续优化我们的代码
window.ssdom = {}
ssdom.getSiblings = function(node) {
let target = node.parentNode.children
let siblings = {length:0}
for(let i=0; i
这种设计模式的优点
- 命名更直观, 更容易理解
- 避免变量覆盖
直接使用元素对象调用函数
但是这样还是有一丢丢麻烦, 我们可不可以直接用节点调用函数呢?
我们来试试吧, 这里我们想到了两种方法
方法一:
我们给Node的原型创建一个getSiblings
和addClass
方法, 那么所有node对象都可以继承这两个方法了
Node.prototype.getSiblings = function() {
let target = this.parentNode.children
let siblings = {length:0}
for(let i=0; i
这样就可以直接用节点调用了
假设我们有下面html
- 选项1
- 选项2
- 选项3
- 选项4
- 选项5
我们可以直接用node节点调用
item3.getSiblings()
item4.addClass({a:true, c:false, b:true})
但是这也有个问题, 如果别人已经在原型定义过同名函数, 那么我们就会覆盖别人的方法,为了避免我们覆盖别人的方法, 我们用另外一种方法试试
方法二:
我们自己造一个函数, 把它叫做jQuery, 然后把node传给这个函数, 这个函数返回一个对象, 对象里面包含上面两个方法, 这样就不会出现覆盖原先的方法的情况了
function jQuery(node) {
return {
getSiblings: function() {
let target = node.parentNode.children
let siblings = {length:0}
for(let i=0; i
这个方法就解决了第一种方法会覆盖别人同名方法的问题
上面的代码, 我们只能传一个节点, 我们再稍微增加一点儿功能, 我们让它也可以接收一个字符串
function jQuery(nodeOrSelector) {
/*************增加接收string类型选择器功能******************/
let node
if(typeof nodeOrSelector === 'string') {
node = document.querySelector(nodeOrSelector)
}else {
node = nodeOrSelector
}
/*******************原来的代码********************/
return {
getSiblings: function() {
let target = node.parentNode.children
let siblings = {length:0}
for(let i=0; i
增加一次选择多个元素功能
再来继续完善功能, 我们来让他可以一次可以选择多个node, 并增加一些有用的API
function jQuery(nodeOrSelector) {
let nodes = {}
if(typeof nodeOrSelector === 'string') {
/****将querySelectorAll获取的nodeList转换成纯伪数组***/
let tmp = document.querySelectorAll(nodeOrSelector)
for(let i=0; i li')
console.log($node2.text())
这里我们的jQuery就造完啦, 当然这个是超级山寨版的, 跟原版的根本比不了...
轮子造完啦
通过上面的例子, 我想告诉大家两点
- 造轮子其实并没有大家想象的那么难, 但是造好用的轮子那就需要很深的功底了
- jquery并没有那么高深莫测, 它其实就是将原生DOM方法进行了增强, 为了让我们更加方便的操作DOM
今天就讲到这里吧