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;
}
复制代码
相关文章
相关标签/搜索