一. 增
1.dom.create 函数,创建节点
dom.create('<div><span>1</span></div>')
在字符串里直接写一段html内容,怎么实现?
window.dom={
create(string){
const container=document.createElement('div')//自己创建一个div容器
container.innerHTML=string //往容器标签里插入HTML内容
return container.children[0]
}
}
有一个bug,如果dom.create('<tr><td>1</td></tr>')
,得到结果是undefined,因为我在函数里创建的是div容器,tr标签只能在table里。
解决办法:把div换成template标签,template可以容纳任何元素。
create(string){
const container=document.createElement('template')
container.innerHTML=string.trim() //把字符串两边的空格删掉
return container.content.firstChild //template元素的子代写法
}
2.dom.after 函数,加弟弟
dom.after(test,span)
在一个标签后插入另一个标签
after(node, node2) {
node.parentNode.insertBefore(node2, node.nextSibling);
}
3.dom.before ,加哥哥
dom.before(test,span)
在test前边插
before(node, node2) {
node.parentNode.insertBefore(node2, node);
}
4.dom.append,加儿子
append(parent, new_node) {
parent.appendChild(new_node);
}
5.dom.wrap,加爸爸
wrap(node, new_parent) {
dom.before(node, new_parent);
dom.append(new_parent, node);
}
二. 删
1.dom.remove,删除节点
remove(node) {
node.parentNode.removeChild(node);
return node; //并且返回这个节点的引用
}
2.dom.empty,清空节点的所有孩子
empty(node) {
//const children = node.childNodes;
//const { childNodes } = node;
const array = [];
let x = node.firstChild;
while (x) {
array.push(dom.remove(x));
x = node.firstChild;
}
return array;
} //删掉一个节点的所有孩子
node.children 和node.childNodes,返回的数组长度会实时变化,所以不能用数组下标i的for循环来删除节点。
三. 改
1.dom.attr,读写一个节点的属性
attr(node, name, value) { //函数重载
if (arguments.length === 3) { //如果传三个实参,写属性
node.setAttribute(name, value);
} else if (arguments.length === 2) { //传前两个实参,读属性值
return node.getAttribute(name);
}
}
根据参数的个数,实现不同的效果,叫重载。
2.dom.text,读,写文本内容
text(node, string) {
if (arguments.length === 2) { //写
if ("innerText" in node) { //适配
node.innerText = string;
} else {
node.textContent = string;
}
} else if (arguments.length === 1) { //读
if ("innerText" in node) {
return node.innerText;
} else {
return node.textContent;
}
}
}
innerText是ie的,textContent是firefox/chrome的,大部分浏览器两者都支持,少数旧的ie只支持innerText。所以可以做一下判断。这种函数的写法叫适配。
3.dom.html,读,写html内容
html(node, string) { //重载
if (arguments.length === 2) {
node.innerHTML = string;
} else if (arguments.length === 1) {
return node.innerHTML;
}
}
4.dom.style,修改/读样式
style(node, name, value) {
if (arguments.length === 3) {
//dom.style(div,'color','red')传三个参数的写样式
node.style[name] = value;
} else if (arguments.length === 2) {
if (typeof name === "string") {
//dom.style(div,'color')传两个参数的读样式
return node.style[name];
} else if (name instanceof Object) {
//dom.style(div,{color:'red',border:''})传对象的写样式
for (let key in name) {
node.style[key] = name[key];
}
}
}
}
5.dom.class.add/remove/has,增加/删除类,判断某元素是否有有个类
class: {
add(node, className) {
node.classList.add(className);
},
remove(node, className) {
node.classList.remove(className);
},
has(node, className) {
return node.classList.contains(className);
}
}
6.dom.on/off,添加/删除一个事件监听
on(node, eventName, fn) {
node.addEventListener(eventName, fn);
},
off(node, eventName, fn) {
node.removeEventListener(eventName, fn);
}
let fn = () => {
console.log("我点击了");
};
dom.on(test, "click", fn);
dom.off(test, "click", fn);
四. 查
1.dom.find,获取标签或者标签们
find(selector, scale) {
return (scale || document).querySelectorAll(selector);
}
dom.find('#test')
传一个选择器作为参数,会返回所有的标签,以数组形式。所以要想获取这个标签本身dom.find('#test')[0]
dom.find('.red',div1)
传两个参数,如果我想找的.red标签同时存在在两个不同的标签中,我只要div1里的那个.red
2.dom.siblings,找兄弟姐妹(排除自己)
siblings(node) {
return Array.from(node.parentNode.children).filter(n => n !== node);
} //children是伪数组
3.dom.travel,遍历所有孩子
travel(childrenList, fn) {
for (let i = 0; i < childrenList.length; i++) {
fn(childrenList[i]);
}
}
4.dom.index,返回节点排行老几
index(node) {
let list = node.parentNode.children; //找爸爸,让爸爸找所有孩子
let i = 0;
for (i = 0; i < list.length; i++) {
if (list[i] === node) {
break;
}
}
return i;
}