一、Node
- DOM是文档对象模型的简称,基本思想为:把结构化文档解析成一系列的节点,再由这些节点组成一个树状结构;
- 所有的节点和最终的树状结构都有规范的对外接口,以达到使用编程语言操作文档的目的,因此DOM可以理解成文档的编程接口
- 严格来说DOM不属于JavaScript但是操作DOM是JavaScript常见的任务
- node是DOM的最小组成单位,一个文档的树形结构就是由各种不同类型的节点组成
- 对于HTML文档,node主要有以下6种类型
1.1 node的属性
- node属性如非特殊情况,所有节点都生效
1.1.1通用属性 nodeName、nodeType
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var span = document.querySelector('span');
console.log(span.nodeName);
console.log(span.nodeType);
console.log(document.nodeName);
console.log(document.nodeType);
</script>
1.1.2 返回当前node的相关节点属性
1.1.2.1 ownerDocument
- 描述:返回当前节点所在的顶层文档对象
- 注意:document节点的ownerDocument属性返回null
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var div1 = document.querySelector('.div1');
var div2 = document.querySelector('#div2');
var span = document.querySelector('span');
console.log(div1.ownerDocument);
console.log(div2.ownerDocument);
console.log(span.ownerDocument);
console.log(document.ownerDocument);
</script>
1.1.2.2 nextSibling
- 描述:nextSibling属性返回紧跟在当前节点后面的第一个同级节点
- nextElementSibling获取下一个相邻的元素
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var div1 = document.querySelector('.div1');
var div2 = document.querySelector('#div2');
var span = document.querySelector('span');
console.log(div2.nextSibling);
console.log(div1.nextSibling.nextSibling);
//查看div1的所有子节点
var el = div1.firstChild;
var i = 1;
while (el) {
console.log(i + '.' + el.nodeName);
el = el.nextSibling;
i++;
}
</script>
1.1.2.3 previousSibling
- 描述:previousSibling和nextSibling用法完全相同,唯一区别是它返回前一个兄弟节点
- previousElementSibling 获取相邻的上一个元素
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var div1 = document.querySelector('.div1');
var div2 = document.querySelector('#div2');
var span = document.querySelector('span');
console.log(div2.previousSibling);
</script>
1.1.2.4 parentNode
- 描述:返回当前节点的父节点
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var div1 = document.querySelector('.div1');
var div2 = document.querySelector('#div2');
var span = document.querySelector('span');
console.log(div2.parentNode.parentNode.parentNode.parentNode.parentNode);
//注意: 如果当前节点没有父节点, 则返回null
console.log(div2.parentNode.parentNode.parentNode.parentNode.parentNode);
</script>
**注意:**一般情况下,一个节点的父节点只可能是三种类型:element节点、document节点、documentframgment节点
1.1.2.5 parentElement
- 描述: parentElement属性返回当前节点的父元素节点
- 如果当前节点没有父节点,或者父节点类型不是Element节点,则返回null
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var div1 = document.querySelector('.div1');
var div2 = document.querySelector('#div2');
var span = document.querySelector('span');
console.log(div2.parentNode.parentNode.parentNode.parentNode);
//注意: 如果当前节点没有父节点, 则返回null
console.log(div2.parentElement.parentElement.parentElement.parentElement);
</script>
1.1.2.6 children
语法:标签对象.children
- 获取标签对象中的所有子标签对象,不包含空白的文本节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
</style>
</head>
<body>
<ul id="ul">
<ul>11</ul>
<ul>21</ul>
<ul>31</ul>
<ul>41</ul>
<ul>51</ul>
</ul>
<div>
<div id="div">
<div>
<div>
<a id="a">哈哈</a>
</div>
</div>
</div>
</div>
<script>
const ul = document.querySelector("#ul");
let lis = ul.children;
for(let i = 0; i < lis.length; i++){
console.log(lis[i].innerHTML);
}
</script>
</body>
</html>
1.1.2.7 closest
标签对象.closest()
- 传入一个CSS选择器,在标签对象的所有上级标签中找到满足CSS选择器条件的上级标签(找祖先元素)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
</style>
</head>
<body>
<ul id="ul">
<ul>11</ul>
<ul>21</ul>
<ul>31</ul>
<ul>41</ul>
<ul>51</ul>
</ul>
<div>
<div id="div">
<div>
<div>
<a id="a">哈哈</a>
</div>
</div>
</div>
</div>
<script>
console.log(document.getElementById("a").closest("div"));
</script>
</body>
</html>
1.1.3 返回node内容属性
1.1.3.1 textContent
- 描述:返回当前节点和它的所有后代节点的文本内容
<div id="divA">This is <span>some</span>text</div>
<script>
var result = document.getElementById('divA').textContent // This is some text
console.log(result);
</script>
1.1.3.2 nodeValue
- 描述:nodeValue属性一般只用于Text节点、Comment节点、XML文档的CDATA节点有效,其他类型的节点一律返回null。
- 返回或设置当前节点的值,格式为字符串
<a href="#" name="a2-name" id="a2-id">hehehe</a>
<button id="btn">oooooo</button>
<script>
var a2_node = document.getElementById('a2-id').firstChild;
console.log(a2_node.nodeValue);
document.getElementById('btn').onclick = function() {
a2_node.nodeValue = '哈哈';
}
</script>
点击按钮前:
单击按钮后:
1.1.4 返回当前node子节点相关属性
1.1.4.1 childNodes
- 描述:childNodes属性返回一个节点集合(NodeList),节点集合中包括当前节点的所有子节点
- childNodes和children的区别在于:childNodes返回指定元素中所有的节点,children返回的是指定元素中所有的子元素
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var div1 = document.querySelector('.div1');
var childList = div1.childNodes;
console.log(childList);
console.log(childList.length);
console.log(childList instanceof Array);
console.log(childList[1]);
</script>
1.1.4.2 firstChild、lastChild
- 描述:返回第一个\最后一个子节点,如果不存在返回null
firstElementChild返回第一个子元素
lastElementChild返回最后一个子元素
<div class="div1">div1
<div id="div2">div2</div>
</div>
<span>这是span标签</span>
<script>
var div1 = document.querySelector('.div1');
console.log(div1.firstChild);
console.log(div1.lastChild);
console.log(document.body.firstChild);
console.log(document.body.lastChild);
</script>
二、node方法
1.appendChild()方法
- 描述:appendChild()方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点
- 语法:node.appendChild(子节点);
- 注意:js创建的节点对象之间是没有文本对象的
<div>
<p>p1</p>
<p>p2</p>
</div>
<span>这是span标签</span>
<button id="but" name="but2">点我</button>
<script>
var div = document.querySelector('div');
var span = document.createElement('span');
span.innerHTML = '这是新的span';
div.appendChild(span);
console.log(div.childNodes);
</script>
2.hasChildNodes()
- 描述:判断一个节点是否有子节点,如果有返回true,否则false
- 语法:node.hasChildNodes();
<div>
<p>p1</p>
<p>p2</p>
</div>
<span>这是span标签</span>
<script>
var div = document.querySelector('div');
var span = document.querySelector('span');
console.log(div.hasChildNodes());
console.log(span.hasChildNodes());
</script>
3.cloneNode()方法
- 描述:cloneNode()方法用于克隆一个节点。它接受一个布尔值作为参数,
- 表示是否同时克隆子节点。默认是false,即不克隆子节点。
- 语法:node.cloneNode(boolean);
注意:
- 拷贝的节点拥有和源节点一样的属性,但不会拷贝绑定的原节点事件
- 深复制:不光拷贝当前节点,还会拷贝所有子节点(深复制)
- 浅复制:只拷贝当前节点,不拷贝子节点(浅复制)
- 赋值一个节点,包括复制节点和属性
<button id="but" name="but2">点我</button>
<script>
var but = document.querySelector('button');
but.onclick = function() {
var newBut = but.cloneNode(true);
document.body.appendChild(newBut);
}
</script>
4.insertBefore()方法
- 描述:insertBefore方法用于将某个节点插入当前节点的指定位置
- 语法:node.insertBefore(newNode,subNode);
说明:
- 一个参数是所要插入的节点
- 第二个参数是当前节点的一个子节点,新的节点将插在这个节点的前面。
<div>
<div class="div1">div1</div>
<div id="div2">div2</div>
</div>
<script>
var div = document.querySelector('div');
var span = document.createElement('span');
span.innerHTML = '这是span';
var result = div.insertBefore(span, div.firstChild);
console.log(result);
console.log(div.childNodes);
</script>
5.removeChild()方法
- 描述:removeChild方法接受一个子节点作为参数,用于从当前节点移除该节点
- 语法:node.removeChild(node); 谋杀式
- 语法:node.child.remove(); 自杀式
- 注意:在js中如果要想删除某一个元素本身,只能通过其对应的父元素来删除,元素是不能自杀的:oDiv.parentNode.removeChild(oDiv)
<div>
<div class="div1">div1</div>
<div id="div2">div2</div>
</div>
<button id="but">点我</button>
<script>
var div = document.querySelector('div');
var div1 = document.querySelector('.div1');
var div2 = document.getElementById('div2');
var but = document.getElementById('but');
but.onclick = function() {
if (div.hasChildNodes()) {
div.removeChild(div.firstChild);
} else {
alert('已经没有子节点了');
}
}
</script>
最初结果:
最后结果:
6.replaceChild(new,origin)方法
- 描述:replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点。
- 语法:var replacedNode = parentNode.replaceChild(newChild, oldChild);
说明:
- 它接受两个参数,第一个参数是用来替换的新节点
- 第二个参数将要被替换走的子节点。它返回被替换走的那个节点。
<div>
<div class="div1">div1</div>
<div id="div2">div2</div>
</div>
<button id="but">点我</button>
<script>
var div = document.querySelector('div');
var div1 = document.querySelector('.div1');
var div2 = document.getElementById('div2');
var but = document.getElementById('but');
but.onclick = function() {
var span = document.createElement('span');
span.innerHTML = '这是sapn';
span.style.color = 'red';
div.replaceChild(span, div2);
}
</script>
替换前:
替换后:
<script>
var but = document.getElementById('but');
but.onclick = function() {
var textNode = document.createTextNode('收藏');
but.replaceChild(textNode, but.firstChild);
but.setAttribute('disabled', 'disabled');
}
</script>
<button id="but">点我</button>
点击按钮前:
点击按钮后:
7.contains()方法
- 描述:contains方法接受一个节点作为参数,返回一个布尔值。
- 判断当前节点是否包含参数节点,包含返回true,否则false
- 语法:node.contains(antherNode);
<div>
<div class="div1">div1</div>
<div id="div2">div2</div>
</div>
<script>
var div = document.querySelector('div');
var div1 = document.querySelector('.div1');
var div2 = document.getElementById('div2');
var result = div1.contains(div2);
console.log(result);
console.log(document.body.contains(div2));
</script>
8.isEqualNode()方法
- 描述:判断两个节点是否相等
- 注意:所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同。
- 语法:node.isEqualNode(node2);
<script>
var div1 = document.querySelector('.div1');
var div11 = document.querySelectorAll('.div1')[0];
var span = document.querySelector('span');
var span1 = document.getElementsByClassName('span1')[0];
console.log(div1.isEqualNode(div11));
console.log(span.isEqualNode(span1));
</script>
<div>
<div class="div1">div1</div>
<div id="div2">div2</div>
</div>
<span class="span1">span</span>
node其他内容
- html元素是网页的根元素
- document.documentElement就指向这个元素
1.视图窗口大小:clientWidth属性、clientHeight属性
2.html元素大小:offsetWidth属性、offsetHeight属性
<script>
//只要当前的窗口大小发生了变化就会显示在这个数值上面
console.log('htmlClientWidth:' + document.documentElement.clientWidth);
console.log('htmlClientHeight:' + document.documentElement.clientHeight);
//html元素多大这里的数值就是多大
console.log('htmlOffsetWidth:' + document.documentElement.offsetWidth);
console.log("htmlOffsetHeight:" + document.documentElement.offsetHeight);
</script>
3.元素位置相关的属性:
- offsetParent属性:获取距离【当前元素】的最靠近的、并且css的position属性不等于static的父元素
<script>
var a = document.getElementById('a-id');
var a_parent = a.offsetParent;
console.log(a_parent);
</script>
<p class="p-id" style="position:relative;">
<span class="span-id">
<a href="#" id="a-id">test-a</a>
</span>
</p>
- offsetTop属性:当前HTML元素左上角相对于offsetParent的垂直位移
- offsetLeft属性:当前HTML元素左上角相对于offsetParent的水平位移
<p class="p-id" style="position:relative;">
<span class="span-id" style="display: inline-block; margin: 15px;">
<a href="#" id="a-id" style="display: inline-block; margin: 25px 55px;">asd</a>
</span>
</p>
<script>
var a = document.getElementById('a-id');
console.log(a.offsetTop);
console.log(a.offsetLeft);
</script>