封装DOM,DOM是JS里面最常用的一个接口,单独使用比较麻烦,故封装起来使用,需要时调用
对象风格
也叫命名空间风格
window.dom 是我们提供的全局对象
然后在dom上挂很多的函数
增删改查
注意:
- 在index.html链接顺序中,dom.js要放在main.js文件上方才能优先访问到,封装的dom库在main.js文件中调用
- 获取到的是否为伪数组,是否需要转换为数组,是否需要获取索引下标才能访问
- 重点记忆需要变通的函数
- each遍历
- 获取元素
- 修改style等 ```javascript window.dom = {
//增create(string) { //用于创建新节点const container = document.createElement("template");container.innerHTML = string.trim();return container.content.firstChild;},after(node, node2) { //在node后面新增node2弟弟(变通式,利用现有insertBefore)node.parentNode.insertBefore(node2, node.nextSibling);},before(node, node2) { //在node前面新增node2哥哥(现有API)node.parentNode.insertBefore(node2, node)},append(parent, node) { //在parent内新增node儿子parent.appendChild(node)},wrap(node, parent) { //在node外新增parent爸爸(变通式)(会覆盖旧爸爸)dom.before(node, parent); //先让node成为parent的哥哥dom.append(parent, node); //再让node成为parent的儿子},//删remove(node) { //删除父亲指定下的儿子node.parentNode.removeChild(node)},empty(node) { //删除父亲名下所有儿子const array = [];let x = node.firstChild;while (x) {array.push(dom.remove(node.firstChild));x = node.firstChild //由于childNode元素会实时变化,因为儿子会发生替位关系,故针对每个大儿子删除,使用while循环不添加计数器}return array},//改attr(node, name, value) { //读&写 属性if (arguments.length === 3) { //重载(根据参数的不同写不同的代码)node.setAttribute(name, value) //现有API ,修改属性} else if (arguments.length === 2) {return node.getAttribute(name) //现有API , 获取属性}},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}}},html(node, string) { //读&写 html内容if (arguments === 2) {node.innerHTML = string;} else if (arguments.length === 1) {return node.innerHTML}},style(node, name, value) { //读&写 styleif (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) { //instanceof判断name是否为Object的实例,返回值为布尔值// dom.style(div,{color:'red'})const object = name;for (let key in object) { //遍历object,把object中所有未知的key声明且读到node.style[key] = object[key] //将object中所有 [key变量下的值] 存入node的style中key变量下}}}},class: { //读&写 classadd(node, className) {node.classList.add(className)},remove(node, className) {node.classList.remove(className);},has(node, className) {return node.classList.contains(className) //记得return返回值得确认}},//改DOM事件on(node, eventName, fn) {node.addEventListener(eventName, fn)},off(node, eventName, fn) {node.removeEventListener(eventName, fn)},//查,用于获取元素(以上均用全局id)find(selector, scope) { //通过选择器和指定范围查找return (scope || document).querySelectorAll(selector) //存在第二个参数scope则在第二个参数的范围里查找,若无则在document中查找},parent(node) { //传入节点,返回节点的爸爸return node.parentNode},children(node) { //传入节点,返回节点的儿子return node.children},siblings(node) { //传入节点,返回兄弟姐妹元素return Array.from(node.parentNode.children).filter(n => n !== node) //得到的伪数组需要转换为数组才能使用filter接口,过滤其他元素,将这些元素存入数组并返回},next(node) { //传入节点,返回弟弟妹妹,排除文本节点let x = node.nextSiblingwhile (x && x.nodeType === 3) { //x存在且x的节点类型为文本节点(同时也需排除x节点不存在的前提)x = x.nextSibling //若该节点属于文本节点,则遍历下个节点,直到元素节点再返回}return x},previous(node) { //传入节点,返回哥哥姐姐,排除文本节点let x = node.previousSiblingwhile (x && x.nodeType === 3) {x = x.previousSibling}return x},each(nodeList, fn) { //对节点列表中的每一个节点遍历调用fn函数for (let i = 0; i < nodeList.length; i++) {fn.call(null, nodeList[i])}},index(node) { //传入节点,获取节点的索引const list = dom.children(node.parentNode) //遍历其父亲的所有孩子,纳入一个列表let i //注意此处i声明在函数外,以便returnfor (i = 0; i < list.length; i++) {if (list[i] === node) {break}}return i}
} ```
