术语
-
库
我们把提供给其他人用的工具代码叫做库。(如:jQuery、underscore)
-
API
库里暴露出来的函数或属性叫做API(应用编程接口)
-
框架
当你的库变得很大,并且需要学习才能看懂;那么这个库就叫做框架。(如;vue/React)
下面我们就来构造一个库(封装DOM)
window.dom = {
create(string) {
const container = document.createElement('template')//template里可以放任何标签
container.innerHTML = string.trim()//trim()用于删除代码中的空格或换行符
return container.content.firstChild
},
after(node, node2) {
node.parentNode.insertBefore(node2,node.nextSibling)
},
before(node, node2) {
node.parentNode.insertBefore(node2, node);
},
append(parent, node) {
parent.appendChild(node);
},
warp(node, parent) {
dom.before(node, parent);
dom.append(parent,node)
},
remove(node) {
node.parentNode.removeChild(node)
return node
},
empty(node) { //此时的node是parent
// const { childNodes } = node //等同于 const childNodes = node.childNodes(表示从他爸爸哪里得到所有儿子)
// let array = []
// for (let i = 0; i < childNodes.length; i++) {
// dom.remove(childNodes[i])
// array.push(childNodes[i])
// }
// return array
//因为childNodes.length会由for循环而发生变化;所以上面的写法不适用,我们还是使用while循环
let x = node.firstChild
let array = []
while (x) {
array.push(dom.remove(node.firstChild))
x = node.firstChild//因为我们删除他的儿子后,他的下一个儿子就会变成大儿子
}
return array
},
attr(node, name, value) { //重载
if (arguments.length === 3) {
node.setAttribute(name, value)
} else if (arguments.length === 2) {
return node.getAttribute(name)
}
},
text(node, string) {//适配
if (arguments.length === 2) {//写
if ('innerText in node') {//写并判断是否支持IE
node.innerText = string
} else {
node.textContent = string
}
} else if (arguments.length === 1) { //读
if ('innerText in node') {
return node.innerText
} else {
return node.textContent
}
}
},
html(node, string) {
if (arguments.length === 2) {//写
node.innerHTML = string
} else if (arguments.length === 1) { //读
return node.innerHTML
}
},
style(node, name, value) {
if (arguments.length === 3) {//根据元素个数判断是读?是写?
node.style(name) = value
} else if (typeof name === 'string') {//根据元素属性判断是读?是写?
return node.style(name)
} else if (name instanceof Object) { //根据元素类型判断是读?是写?
for (let key in object) {
node.style[key] = object[key]
}
}
},
class: {
add(node, className) { //添加
node.classList.add(className)
},
remove(node, className) { //删除
node.classList.remove(className)
},
has(node, className) {//检查是否存在
return node.classList.contains(className)
}
},
on(node, eventName, fn) {
node.addEventListener(eventName,fn)
},
off(node, eventName, fn) {
node.removeEventListener(eventName,fn)
},
find(selector, scope) { //给我一个选择器和一个范围
return (document || scope).querySelectorAll(selector)//返回一个数组
},
parent(node) {
return node.parentNode
},
children(node){
return node.children
},
sibling(node) {
return Array.from(node.parentNode.children).filter(n=>n!==node)//Array.from()表示将括号内的元素变成数组
},
next(node) {
let x = node.nextSibling
while (x && x.type === 3) {
x = x.nextSibling
}
},
previous(node) {
let x = node.previousSibling
while (x && x.type === 3) {
x = x.previousSibling
}
return x
},
each(nodeList, fn) {
for (let i = 0; i < nodeList.length; i++) {
fn.call(null,nodeList[i])
}
},
index(node) {
let list = dom.children(node.parentNode)
let i
for (i = 0; i < list.length; i++) {
if (list[i] === node)
break
}
return i
}
};
上面就是一个简单的封装源码