虽然如今咱们在开发中已经用不到本身操做DOM
了,以前有JQ
,如今更是有VUE
、REACT
两大框架供咱们使用,可是咱们也有必要了解下,关于原生JS
中的DOM
操做问题。javascript
DOM
节点类型及获取节点的方法咱们认为在页面中全部呈现的内容,都是DOM文档中的一个节点(node),例如:元素标签是元素节点、注释的内容是注释节点、文本内容是文本节点、document是文档节点...java
document
描述节点和节点之间的关系属性,基于这些属性能够获取到指定的节点node
[CONTAINER].childNodes
[CONTAINER].children
IE
低版本浏览器中,也会把注释看成元素节点[NODE].parentNode
[NODE].previousSibling
[NODE].previousElementSibling
[CONTAINER].nextSibling
[CONTAINER].nextElementSibling
[CONTAINER].firstChild
[CONTAINER].firstElementChild
[CONTAINER].lastChild
[CONTAINER].lastElementChild
全部方法和属性,都是为了快速获取到咱们想要操做的DOM元素或者节点的浏览器
function children(container) {
// 获取全部的子节点,遍历这些节点,全部NODETYPE===1的就是咱们想要的元素子节点
var nodeList = container.childNodes,
result = [];
for (var i = 0; i < nodeList.length; i++) {
var itemNode = nodeList[i];
if (itemNode.nodeType === 1) {
// 元素节点
result.push(itemNode);
}
}
return result;
}
var arr = children(box);
console.log(arr);
复制代码
JQ
中的prevAll
这个方法就是干这个的,咱们本身封装一个框架
//=> 已知:previousElementSibling是获取上一个哥哥元素节点(兼容性) previousSibling获取上一个哥哥节点(没有兼容性的)
function prevAll(node) {
let result = [];
// 获取它爹
let parent = node.parentNode;
// 获取它爹中的儿子(本身和他全部的兄弟)
let nodeList = parent.childNodes;
// 循环全部节点,元素类型的是咱们想要的,而且找到当前节点后就不在循环了
for (let i = 0; i < nodeList.length; i++) {
let item = nodeList[i];
if (item === node) {
// 找到的是本身
break;
}
// 找的不是本身,咱们把元素节点存储起来
if (item.nodeType === 1) {
result.push(item);
}
}
return result;
}
复制代码
//=> 循环不知道具体次数(不知道找多少次) =>while循环
function prevAll(node) {
let prev = node.previousSibling,
result = [];
// 循环找他的哥哥,一直到没有哥哥了为止
while (prev !== null) {
// 把找到的哥哥中是元素节点的存储起来
if (prev.nodeType === 1) {
result.unshift(prev);
}
prev = prev.previousSibling;
}
return result;
}
复制代码
同上题同样,咱们一样写两种方法ui
function nextAll(node) {
// 获取其父亲中全部的儿子
let nodeList = node.parentNode.childNodes,
result = [];
// 倒着从最后一项开始循环
for (let i = nodeList.length - 1; i >= 0; i--) {
let item = nodeList[i];
if (item === node) break;
item.nodeType === 1 ? result.unshift(item) : null;
}
return result;
}
复制代码
function nextAll(node) {
let result = [],
next = node.nextSibling;
while (next !== null) {
next.nodeType === 1 ? result.push(next) : null;
next = next.nextSibling;
}
return result;
}
复制代码
function siblings(node) {
// 全部的儿子中必定包含了,我和个人兄弟们
let nodeList = node.parentNode.childNodes,
result = [];
// 依次遍历每个节点,把非元素和我自己除外,其他的存储起来
for (let i = 0; i < nodeList.length; i++) {
let item = nodeList[i];
if (item.nodeType === 1 && item !== node) {
result.push(item);
}
// 上面的 if 判断条件也可改写为下面的
// if (item.nodeType !== 1 || item === node) {
// continue;
// }
// result.push(item);
}
return result;
}
复制代码
function siblings(node) {
// 分别调用两个方法获取全部的哥哥和全部的弟弟,就是全部的兄弟
return prevAll(node).concat(nextAll(node));
}
复制代码
function index(node) {
// 它有几个哥哥,那么它的索引就是几
return prevAll(node).length;
}
复制代码