雖然如今咱們在開發中已經用不到本身操做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;
}
複製代碼