DOM操做之——DOM節點類型及屬性

雖然如今咱們在開發中已經用不到本身操做DOM了,以前有JQ,如今更是有VUEREACT兩大框架供咱們使用,可是咱們也有必要了解下,關於原生JS中的DOM操做問題。javascript

  • 此次咱們介紹一下DOM節點類型及獲取節點的方法

咱們認爲在頁面中全部呈現的內容,都是DOM文檔中的一個節點(node),例如:元素標籤是元素節點、註釋的內容是註釋節點、文本內容是文本節點、document是文檔節點...java

1、節點類型

一、文檔節點

  • document
  • 重點記憶屬性:
    • nodeType(節點類型):9
    • nodeName(節點名字):「#document」
    • nodeValue(節點文本內容):null

二、元素節點

  • 全部元素標籤
  • 重點記憶屬性:
    • nodeType(節點類型):1
    • nodeName(節點名字):「大寫標籤名」
    • nodeValue(節點文本內容):null

三、文本節點

  • 文字、標籤之間的空格和換行也被看成文本節點
  • 重點記憶屬性:
    • nodeType(節點類型):3
    • nodeName(節點名字):「#text」
    • nodeValue(節點文本內容):文本內容

四、註釋節點

  • 註釋內容
  • 重點記憶屬性:
    • nodeType(節點類型):8
    • nodeName(節點名字):「#comment」
    • nodeValue(節點文本內容):註釋內容

2、獲取節點的方式

描述節點和節點之間的關係屬性,基於這些屬性能夠獲取到指定的節點node

一、獲取全部子節點——節點集合

  • 語法:[CONTAINER].childNodes
  • 獲取當前容器中全部的子節點
  • 包含各類類型的節點
  • 獲取到的是一個節點集合,包含容器中的全部類型節點(空格換行是文本節點)

二、獲取元素子節點——元素集合

  • 語法:[CONTAINER].children
  • 獲取當前容器中全部的元素子節點
  • 獲取的是一個元素集合,只有元素節點
  • 只有元素標籤的,在IE低版本瀏覽器中,也會把註釋看成元素節點

三、獲取父節點

  • 語法:[NODE].parentNode
  • 獲取某一個節點的父節點

四、獲取一個哥哥節點

  • 語法:[NODE].previousSibling
  • 獲取某一個節點的上一個哥哥節點

五、獲取一個哥哥元素節點

  • 語法:[NODE].previousElementSibling
  • 獲取某一個節點的上一個哥哥元素節點(不兼容IE低版本瀏覽器)

六、獲取一個弟弟節點

  • 語法:[CONTAINER].nextSibling
  • 獲取某一個節點的下一個弟弟節點

七、獲取一個弟弟元素節點

  • 語法:[CONTAINER].nextElementSibling
  • 獲取某一個節點的下一個弟弟元素節點(不兼容IE低版本)

八、獲取第一個子節點

  • 語法:[CONTAINER].firstChild
  • 獲取容器中第一個子節點

九、獲取第一個元素子節點

  • 語法:[CONTAINER].firstElementChild
  • 獲取容器中第一個元素子節點(不兼容IE低版本)

十、獲取最後一個字節點

  • 語法:[CONTAINER].lastChild
  • 獲取容器中最後一個字節點

十一、獲取最後一個元素子節點

  • 語法:[CONTAINER].lastElementChild
  • 獲取容器中最後一個元素子節點(不兼容IE低版本)

全部方法和屬性,都是爲了快速獲取到咱們想要操做的DOM元素或者節點的瀏覽器

思惟導圖

3、需求練習

一、封裝一個方法:獲取指定容器CONTAINER中的全部元素子節點,須要兼容全部的瀏覽器

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;
}
複製代碼

方法二:獲取當前節點的哥哥節點,再獲取哥哥節點的哥哥節點...一直找到沒有哥哥節點爲止(沒有哥哥節點,結果爲NULL); 再查找的過程當中,把全部找到的元素節點存儲起來便可;

//=> 循環不知道具體次數(不知道找多少次) =>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;
}
複製代碼
相關文章
相關標籤/搜索