DOM知识详解
1.什么是DOM
DOM是一种文档对象模型,同时也是用于HTML编程的接口,通过DOM来操作页面中的元素。当HTML页面被实现加载的时候,浏览器会创建一个DOM,给文档提供了一种新的逻辑结构,并且可以改变内容和结构。
DOM是面向对象,并且定义了修改文档所需要的对象,各个对象之前的关系,我们可以也页面上的DOM看成一个树状结构,通过JS,对HTML文档进行添加排版,JS要想访问HTML中的元素,就要通过对象模型来获得。
2.DOM获取元素的方法
2.1获取非常规DOM
非常规DOM包括HTML, head, body
// 2.1 HTML语法: document.documentElement
var htmlEle = document.documentElement
console.log(htmlEle)
// 2.2 head 语法: document.head
var headEle = document.head
console.log(headEle)
// 2.3 body 语法: document.body
var bodyEle = document.body
console.log(bodyEle)
2.2获取常规的DOM
JS在获取常规元素时与CSS一样,可以通过类名,标签名,ID名来获取元素
2.2.1通过类名来获取标签
<div class="box" id="box2"> 我是具有class的box2 </div>
<div class="box"> 我是具有class的box1 </div>
<p>我是一个P标签</p>
<div class="box"> 我是具有class的box3 </div>
<script>
var oBox = document.getElementsByClassName('box')
//获取class名为'box'的元素
console.log(oBox)
</script>
oBox 是一个伪数组, 想要获取到某一个元素, 可以通过下标
伪数组: 长得和数组类似, 有下标有length, 但是没有数组的常用方法
不管页面具有这个 类名的 元素 有多少个, 获取到的永远是 伪数组的形式
2.2.2通过标签名来获取标签
<div class="box" id="box2"> 我是具有class的box2 </div>
<div class="box"> 我是具有class的box1 </div>
<p>我是一个P标签</p>
<div class="box"> 我是具有class的box3 </div>
<script>
var oDiv = document.getElementsByTagName('box')
//获取所有的div
console.log(oDiv)
</script>
oDiv 也是一个伪数组, 想要获取到某一个元素, 可以通过下标
2.2.3通过ID名去获取标签
<div class="box" id="box2"> 我是具有class的box2 </div>
<div class="box"> 我是具有class的box1 </div>
<p>我是一个P标签</p>
<div class="box"> 我是具有class的box3 </div>
<script>
var oBox2 = document.getElementById('box2')
//获取ID为'box2'的元素
console.log(oBox2)
</script>
因为 ID 通常都是独一无二的
所以这里获取到的就是一个ID 名为’box2’ 的标签, 而不是一个伪数组
2.2.4选择器的形式
获取满足条件的第一个标签
<div class="box" id="box2"> 我是具有class的box2 </div>
<div class="box"> 我是具有class的box1 </div>
<p>我是一个P标签</p>
<div class="box"> 我是具有class的box3 </div>
<script>
var myDiv = document.querySelector('.box')
//querySelector: 获取到满足条件的第一个标签
console.log(myDiv)
</script>
获取满足条件的所有标签
<div class="box" id="box2"> 我是具有class的box2 </div>
<div class="box"> 我是具有class的box1 </div>
<p>我是一个P标签</p>
<div class="box"> 我是具有class的box3 </div>
<script>
var myDivAll = document.querySelectorAll('.box')
//querySelector: 获取到满足条件的所有标签
console.log(myDivAll)
</script>
3.innerHTML和innerText
<div>
我是 DIV 的文本
<p>
我是 P 的文本
<span>
我是 SPAN 的文本
</span>
</p>
<div>
我是内部 DIV 的文本
</div>
</div>
<script>
// 获取页面的 DIV 标签
var oDiv = document.querySelector('div') // 获取满足条件的第一个标签 条件: div
console.log(oDiv)
</script>
3.1获取属性
innerHTML : 获取到标签内部的文本与HTML结构
innerText : 只会获取到页面结构的文本内容,HTML结构会被忽略掉
<div>
我是 DIV 的文本
<p>
我是 P 的文本
<span>
我是 SPAN 的文本
</span>
</p>
<div>
我是内部 DIV 的文本
</div>
</div>
<script>
console.log(oDiv.innerHTML) // 获取到标签内部的文本与HTML结构
console.log(oDiv.innerText) // 获取到页面的文本内容
</script>
3.2操作元素的属性
innerHTML : 赋值时,会识别字符串中的html结构.如果有实际的标签,会把它当成标签渲染到页面上
innerText : 赋值时,不会识别字符串中的html结构.
如果有实际的标签,会把它当成字符串渲染到页面是上
如图所示为innerHTML
<script>
oDiv.innerHTML = '1234567890'
oDiv.innerHTML = '<div>1234567890<div>'
</script>
如图所示为innerText
<script>
oDiv.innerText = '1234567890'
oDiv.innerText = '<div>1234567890<div>'
</script>
4.获取元素的某些属性
4.1获取元素
<div class="box" a="100" b="200">我是一个具有很多属性的 DIV 标签</div>
<script>
var oBox = document.getElementsByClassName('box')[0] //获取页面中第一个class名为box的元素
console.log(oBox)
</script>
4.2获取元素的某些属性
语法: 元素.getAttribute(‘要查询的属性名’)
<script>
//获取元素的class属性
console.log(oBox.getAttribute('class'))
//获取元素的a属性
console.log(oBox.getAttribute('a'))
//获取元素的b属性
console.log(oBox.getAttribute('b'))
</script>
4.3设置某些元素的某些属性
语法:元素.setAttribute(‘要设置的属性名’,‘要设置的属性值’)
<script>
//将属性a的值修改为A
oBox.setAttribute('a', 'A')
//将属性b的值修改为B
oBox.setAttribute('b', 'B')
//原本div里本没有c这个属性值,执行此操作就不在是修改,而为新增一个c属性名,值为C
oBox.setAttribute('c', 'C')
</script>
4.4移出元素的某个属性**
语法: 元素.removeAttribute(‘要移除的属性名’)
<script>
//移除b这个属性名,同时值也会一同被移除
oBox.removeAttribute('b')
</script>
5.H5自定义属性
语法:data-属性名=‘‘属性值’’
HTML和css部分
<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>
</head>
<body>
<div A="123" data-B="123456789">H5新增自定义属性</div>
JavaScript部分
<script>
//获取div
var oDiv = document.querySelector('div')
// 获取 H5 自定义属性
// 1. 获取语法: 元素.dataset.属性名
console.log(oDiv.dataset.B)
// 2. 设置语法
oDiv.dataset.B = 'abcd' // 标签中实际拥有; 做修改操作
oDiv.dataset.age = 18 // 标签中实际没有; 做新增操作
// 3. 删除
delete oDiv.dataset.age
</script>
6.获取元素类名
<div class="item box">我是一个具有两个类名的 DIV</div>
<script>
//获取元素类名
var oDiv = document.querySelector('div')
// 1. 获取语法 元素.className
console.log(oDiv.className)
// 2. 设置语法 元素.className = '新的类名'
oDiv.className = oDiv.className + ' new_box'
// 3. 第二种获取语法
console.log(oDiv.classList)
// 4. 第二种设置语法
oDiv.classList.add('new_box')
// 5. 删除语法
oDiv.classList.remove('box')
</script>
7.获取元素样式
HTML和css部分
<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>
.box {
width: 300px;
height: 300px;
background-color: pink;
}
</style>
<div class="box"> 我是一个具有样式的div </div>
JavaScript部分
语法: 元素.style.某个CSS属性
<script>
var oBox = document.getElementsByClassName('box')[0]
// 1. 获取元素样式
console.log(oBox.style.width)
console.log(oBox.style.height)
// console.log(oBox.style.background-color) // 错误写法
console.log(oBox.style['background-color']) // 中括号语法
console.log(oBox.style.backgroundColor) // 驼峰命名
// 2. 设置元素样式 ---> 只能设置给行内
oBox.style.backgroundColor = 'blue'
//获取元素样式 (非行内) 注意: 这种方式获取到的 是 只读的属性
//只读: 只能获取到, 但是不允许修改
console.log(window.getComputedStyle(oBox).width)
console.log(window.getComputedStyle(oBox).backgroundColor)
</script>
8.获取DOM节点
8.1获取DOM子节点
<div class="box">
<p>123</p>
<span>abc</span>
</div>
<div id="box1"></div>
<script>
// 1. 获取元素的子节点
var oDiv = document.querySelector('div')
console.log(oDiv.children) // 获取元素的所有 子级元素节点(只能获取到标签)
console.log(oDiv.childNodes)
//oDiv.childNodes: ---> NodeList(5) [text, p, text, span, text]
//获取所有的 子级节点(会把换行识别为一个文本, 标签当成 元素节点)
//div 结束标签的位置开始, 到p标签开始位置的换行会被识别为一个 text
//p 标签会被识别为一个 元素节点
//p 结束标签到 span 开始标签前 的换行 会被识别为一个 text
//span 标签会被是被识别为一个 元素节点
//span 标签结束位置到 div 结束标签前 的换行 会被识别为一个 text
</script>
8.2获取DOM第一个子节点
<div class="box">
<p>123</p>
<span>abc</span>
</div>
<script>
var oDiv = document.getElementsByTagName('div')[0]
console.log(oDiv.firstChild) // 获取的是 元素内部 第一个 子节点 (不一定是 子元素节点)
//获取到div节点内的第一个子节点
//注意此时并不是获取到了第一个元素节点,
//而是div开始标签后到p开始标签前的一段换行, 这一段被识别为 text(文本节点)
//除非你的 HTML 结构 不写换行
console.log(oDiv.firstElementChild) // 获取的是元素内部第一个子元素节点
</script>
8.3获取DOM最后一个子节点
<div class="box">
<p>123</p>
<span>abc</span>
</div>
<script>
var oDiv = document.querySelector('div')
console.log(oDiv.lastChild)
//获取最后一个子节点, 也就是 span结束标签, 到div结束标签前的一个换行, 这里会被识别为 text
console.log(oDiv.lastElementChild)
// 获取最后一个子元素节点 ---> span
</script>
8.4获取兄弟节点
<ul>
<li id="a">1</li>
<li id="b">2</li>
<li id="c">3</li>
</ul>
<script>
var oli = document.getElementById('b')
// 获取下一个兄弟节点
console.log(oli.nextSibling) // 获取下一个兄弟节点 ---> #text
// 获取下一个兄弟元素节点
console.log(oli.nextElementSibling) // 获取下一个兄弟元素节点 ---> <li id="c"></li>
// 获取上一个兄弟节点
console.log(oli.previousSibling) // 获取上一个兄弟节点 ---> #text
// 获取上一个兄弟元素节点
console.log(oli.previousElementSibling) // 获取上一个兄弟元素节点 ---> <li id="a"></li>
</script>
8.5获取父级节点
<div>
<ul>
<li id="a">1</li>
<li id="b">2</li>
<li id="c">3</li>
</ul>
</div>
<script>
// 获取元素的 父级节点
var oli = document.getElementById('b')
console.log(oli)
console.log(oli.parentNode)
</script>
8.6节点分类
<ul A="100" B="200">
<li>我是ul的子级</li>
</ul>
<script>
var oUl = document.querySelector('ul')
// 1. 元素节点
var ele = oUl.firstElementChild
// 2. 文本节点
var text = oUl.firstChild
// 3. 属性节点
var attr = oUl.attributes[0]
//nodeType 节点类型
console.log(ele.nodeType) // 元素节点打印1
console.log(text.nodeType) // 文本节点打印3
console.log(attr.nodeType) // 属性节点打印2
//nodeName 节点名称
console.log(ele.nodeName) // 元素节点节点名称大写的LI
console.log(text.nodeName) // 文本节点名称#text
console.log(attr.nodeName) // 属性节点名称就是属性名
//nodeValue 节点的值
console.log(ele.nodeValue) // 元素节点是没有 nodeValue
console.log(text.nodeValue) // 文本节点是实际的文本的值
console.log(attr.nodeValue) // 属性节点是实际属性值
</script>
9.操作DOM
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
// 1.1 创建 元素节点
var myLi = document.createElement('li')
// 1.2 创建文本节点
var myStr = document.createTextNode('222222222222222')
myLi.appendChild(myStr)
console.log(myLi)
// console.log(myStr)
// 获取UL标签
var oUl = document.querySelector('ul')
var oLi = document.getElementsByTagName('li')[1]
// 2.1 增加dom(添加到指定父节点的最后)
oUl.appendChild(myLi)
// 2.2 增加dom(添加到指定父节点的最后) 语法:父节点.insertBefore(要插入的新节点, 插入到那个节点前(传递Null的话是插入到父节点最后))
oUl.insertBefore(myLi, null)
// 2.3 增加dom(添加到父节点的最前边)
oUl.insertBefore(myLi, oUl.firstElementChild)
// 3. 删除DOM 父节点.removeChild(要删除的节点)
oUl.removeChild(oUl.firstElementChild)
// 4. 修改某一个节点 父节点.replaceChild(新的节点, 要被修改的节点)
oUl.replaceChild(myLi, oLi)
//5.克隆DOM
//复制(克隆)一个 LI
//语法:想要复制的节点.cloneNode(参数布尔值)
//参数 false 不克隆子节点 默认为false(可不写)
//参数 true 克隆子节点
var newLi = oLi.cloneNode(true)
console.log(newLi)
oUl.appendChild(newLi)
</script>
10.获取元素偏移量
<style>
* {
padding: 0;
margin: 0;
}
.box1 {
width: 400px;
height: 400px;
background-color: pink;
position: relative;
}
.box2 {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute;
left: 100px;
top: 200px;
}
</style>
<div class="box1">
<div class="box2"></div>
</div>
<script>
// 0. 获取元素
var box2 = document.querySelector('.box2')
// 1. 获取元素相对父级 元素.offsetParent
console.log(box2.offsetParent)
// 2. 获取元素的偏移量
console.log( box2.offsetLeft) //相对于父级元素横向偏移
console.log( box2.offsetTop) //相对于父级元素纵向偏移
</script>
11.获取元素尺寸与浏览器窗口尺寸
<style>
* {
padding: 0;
margin: 0;
}
div {
width: 4000px;
height: 5000px;
background-color: pink;
}
</style>
<div></div>
<script>
var oDiv = document.querySelector('div')
// 获取元素尺寸(占地面积)
// 1. offsetXXX ---> 实际宽度/高度 + padding + border
console.log( oDiv.offsetWidth)
console.log( oDiv.offsetHeight)
// 2. clientXXX ---> 实际宽度/高度 + padding
console.log( oDiv.clientWidth)
console.log( oDiv.clientHeight)
// 获取浏览器窗口尺寸
// 1. window.innerXXX ---> 计算时 会包含浏览器的滚动条
console.log( window.innerWidth)
console.log( window.innerHeight)
// 2. document.documentElement.clientXXX ---> 计算时 不会计算滚动条(只计算浏览器的可视区域)
console.log( document.documentElement.clientWidth)
console.log( document.documentElement.clientHeight)
</script>