DOM的基本概念
DOM: 文档对象模型, 其实就是操作 html 中标签的一些能力
比如:
获取一个元素(标签)
移除一个元素
创建一个元素
向页面添加一个元素
给元素绑定一个 事件
获取元素的属性
给元素添加一些 css 样式
......
DOM 的核心是 document 对象
document 对象是 JS 内置的一个对象, 里面存储着专门用来操作元素的各种方法
DOM对象: 页面中的标签, 我们通过 JS 获取到以后, 就把这个对象叫做 DOM对象(DOM节点)
获取元素
1.获取非常规元素 非常规标签有(html,head,body)
document.documentElement -> 获取html标签
例: console.log(document.documentElement)
document.head -> 获取head标签
例: console.log(document.head)
document.body -> 获取body标签
例: console.log(document.body)
2.获取常规元素
2.1 通过 ID 名获取标签
语法: document.getElementById('ID名')
例: var box = document.getElementById('box')
console.log(box)
2.2 通过 class 名获取标签
语法:document.getElementsByClassName('class名')
注意: 因为在页面中可能会有多个元素的 class 相同,所以获取到的是一组元素,
获取到后会把元素放在一个长得很像数组一样的 数据结构内, 但他并不是数组,我们称之为 伪数组
伪数组:长得很像数组, 也是通过索引排序, 但是没有数组的方法
例: 获取到页面中 class 名为 box1 的标签
var box1 = document.getElementsByClassName('box1')
console.log(box1)
console.log(box1[0])
console.log(box1[1])
console.log(box1[2])
2.3 通过 标签名获取
语法: document.getElementsByTagName('标签名')
注意: 获取到的也是一个长得很像数组一样的数据结构(伪数组)
想要准确的获取到标签元素,我们需要通过索引来帮助我们拿到
例: 获取到页面中 标签名为 div 的标签
var divs = document.getElementsByTagName('div')
console.log(divs) //[div#box, div.box1, div.box1, div.box1, box: div#box]
console.log(divs[0])
2.4 按照选择器的形式来获取元素
2.4.1 querySelector, 这个方法允许我们想写 css 的时候的选择器一样获取标签
语法:document.querySelector('选择器')
注意:这个方法只能获取到一个元素, 就是满足条件的第一个元素
例: var box2 = document.querySelector('.box1')
console.log(box2)
var box3 = document.querySelector('div')
console.log(box3)
2.4.2 querySelectorAll, 该方法与 querySelector 选择器类似,只不过会将所有满足条件的元素都获取到, 也是放在一个伪数组内
例: var box4 = document.querySelectorAll('.box1')
var box5 = document.querySelectorAll('div')
console.log(box4)//[div.box1, div.box1, div.box1]
console.log(box5)//[div#box, div.box1, div.box1, div.box1]
操作属性
我们获取到元素以后, 可以直接操作 DOM 的属性, 然后直接把效果展示在页面
1.innerHTML
获取元素内部的 HTML 结构
我们也可以直接给这个属性重新赋值,达到修改页面的效果
例: var oDiv = document.querySelector('#box')
console.log(oDiv.innerHTML)
oDiv.innerHTML = '<p><span>各位, 早上好~~~这个文本是通过JS来设置的</span></p>'
2.innerText
获取元素内部得到文本(只能获取到文本, 获取不到 html 标签)
我们也可以直接给这个属性重新复制,达到修改页面的效果
例: var oDiv = document.querySelector('#box')
oDiv.innerText = '<p><span>各位, 早上好~~~这个文本是通过JS来设置的</span></p>'
元素属性
1. 获取元素的某些属性
语法:元素.getAttribute('要查询的属性名')
返回值:查询到属性时返回对应的属性值, 没有查询到时 直接返回 null
2. 修改元素的某些属性
语法:元素.setAttribute('对应的属性名', '对应的属性值')
注意:如果元素没有对应的属性名, 那么相当于是新增的一个属性
3. 删除元素的某些属性
语法:元素.removeAttribute('要删除的属性名')
h5 自定义属性
data- 表示该属性是一个自定义属性!!!!!!
data- 后边的内容才是属性名, 当前案例中属性名为a, 不是data-a
= 后边的内容是属性值
每一个 元素/DOM节点 天生自带一个属性, 叫做dataset, 是一个类似对象的数据结构
操作: 查询 增加 删除
0.获取标签
var oDiv = document.querySelector('div')
1.访问元素的 dataset 属性 查询
console.log(oDiv.dataset.a) //100
2. 增加一个 h5 自定义属性
oDiv.dataset.age = 18 // 标签中没有这个自定义属性, 所以是新增
oDiv.dataset.a = 'QF666' //标签中有这个自定义属性, 相当于做了修改操作
3. 删除
delete oDiv.dataset.a
获取元素样式和类名
获取元素样式
语法:元素.style.某个属性
注意:我们也可以给这个语法重新赋值, 达到修改元素样式的效果
实例 操作:
<div class="box"></div>
0. 获取元素
var oDiv = document.querySelector('.box')
1. 获取元素样式 (只能获取行内样式)
console.log(oDiv.style.weight)
console.log(oDiv.style.height)
解决方法
console.log(oDiv,style['background-color'])
console.log(odiv.style.backgroundColor)
2.设置元素样式 (只能设置行内样式)
oDiv.style.width = 666 + 'px'
oDiv.style.background = 'red'
3.获取 非行内样式 (也可以获取到行内样式)
语法:window.getComputedStyle(元素).要查询的 css 属性
注意:这种方式获取到的属性 是只读的(能获取到, 但不允许修改)!!!
console.log(window.getComputedStyle(oDiv).width)
console.log(window.getComputedStyle(oDiv).backgroundColor)
4. className 专门用来操作元素的 类名
语法:元素.className 我们也可以给他重新赋值,来达到修改元素的类名
例: oDiv.className = 'new_box'
console.log(oDiv.className)
获取 元素类名
1. className 专门用来操作元素的 类名
语法:元素.className 我们也可以给他重新赋值,来达到修改元素的类名
2. classList
新增
语法: 元素名.classList.add('新增元素名')
删除
语法: 元素名.classList.remove('元素名')
DOM 节点
一般来说我们分为三个大类
元素节点(标签)
通过 getElementBy... 获取到的都是元素节点
文本节点(标签内的文字)
通过 innerText 获取到的就是元素的文本节点
属性节点(标签上的属性)
通过 getAttribute 获取到的都是属性节点
获取子节点
1. 获取某一节点下 所有的 子一级 节点, 获取到的是一个 伪 数组
语法: 元素.childNodes
2.获取某一节点下 所有的 子一节 元素节点 获取到的是一个 伪 数组
语法: 元素.children
3. 获取某一节点下子一级的 第一个节点
语法: 元素.firstChild
4. 获取某一节点下子一级的 最后一个节点
语法: 元素.lastChild
5. 获取某一节点下子一级的 第一个元素节点
语法: 元素.firstElementChild
6. 获取某一节点下子一级的 最后一个元素节点
语法: 元素.lastElementChild
实例: <div>
<p>你好</p>
<span>测试文本</span>
<h1> JS 是世界上最优美的语言</h1>
</div>
0. 获取元素
var oDiv = document.querySelector('div')
1. childNodes
console.log(oDiv.childNodes)
注: 拿到的是一个伪数组, 里边有 7 个节点
[0]: text 从 <div> 一直到 <p> 中间有一个换行和一堆空格 这是一个文本节点
[1]: p 这个就是 p 标签, 他是第二个节点, 这是一个 元素节点
[2]: text 从 </p> 一直到 <span> 中间有一个换行和一堆空格 这是一个文本节点
......
2. children
console.log(oDiv.children) 这里只有 div 内部的标签
3. firstChild
console.log(oDiv.firstChild) #text
4. lastChild
console.log(oDiv.lastChild) #text
5. firstElementChild
console.log(oDiv.firstElementChild)
6.lastElementChild
console.log(oDiv.lastElementChild)
获取兄弟节点
var oSpan = document.querySelector('span')
1.获取对应的 下一个兄弟节点
语法:元素.nextSibling
例: console.log(oSpan.nextSibling)
2. 获取对应的 上一兄弟节点
语法:元素.previousSibling
例: console.log(oSpan.previousSibling)
3. 获取对应的 下一个兄弟元素节点
语法:元素.nextElementSibling
例: console.log(oSpan.nextElementSibling)
4. 获取对应的 上一个兄弟元素节点
语法:元素.previousElementSibling
例: console.log(oSpan.previousElementSibling)
获取父节点与属性节点
1. 父节点:
语法:元素.parentNode
2. 获取元素的所有属性节点
语法: 元素.attribute
节点属性
1.nodeType 节点属性
节点中的一个属性 nodeType 能够区分当前节点是什么类型
元素节点 返回 1
属性节点 返回 2
文本节点 返回 3
2.nodeName 节点名称
元素节点 -> 大写的标签名 (LI / UL / DIV)
属性节点 -> text (属性名)
文本节点 -> #text
3. nodeValue 节点的值
元素节点 -> 没有 nodeValue 也就会输出 null
属性节点 -> 对应的属性值
文本节点 -> 对应的文本内容
实例:<ul text="我是 UL 的一个属性">
<li>holle</li>
</ul>
0. 获取元素
var oUl = document.querySelector('ul')
1. 元素节点
var eleNode = oUl.firstElementChild
2.属性节点
var attrNode = oUl.attributes[0]
3.文本节点(换行和空格)
var textNode = oUl.firstChild
nodeType
console.log('元素节点:', eleNode.nodeType)
console.log('属性节点:', attrNode.nodeType)
console.log('文本节点:', textNode.nodeType)
nodeName
console.log('元素节点:', eleNode.nodeName)
console.log('属性节点:', attrNode.nodeName)
console.log('文本节点:', textNode.nodeName)
nodeValue
console.log('元素节点:', eleNode.nodeValue)
console.log('属性节点:', attrNode.nodeValue)
console.log('文本节点:', textNode.nodeValue)
操作 DOM 节点
常规意义上的‘增删改查’ (在页面上增加一个节点, 首先,你应该先有一个节点)
1.在 JS 中创建 一个节点
语法: document.createElement('要创建的标签名')
创建一个文本节点 (仅做了解) 语法:document.createTextNode
2.向页面增加一个节点
语法1: 元素.appendChild(要添加的节点)
作用: 向元素的末尾追加一个节点
语法2: 元素.insertBefore(要插入的节点, 插入到哪个节点的前面)
注: 两个参数是必填项
第二个参数传递正常节点时, 代表插入到这个节点的前面
第二个节点传递的是 null时, 表示插入带 元素 到的末尾
3.删除页面得到某一个节点
语法1: 父节点.removeChild(要删除的节点)
语法2: 节点.remove()
作用:把当前节点删除
4.修改页面的某一个节点
语法: 父节点.replaceChild(新节点, 旧节点/要被修改的节点)
作用: 将页面中的某一个节点 做一个替换
5.获取页面的某一个节点
之前获取 元素 的方法
6.克隆一个节点(把一个节点复制出一个一模一样的)
语法: 节点.cloneNode(参数)
参数:默认是 false ,表示不克隆后代节点(只克隆标签不克隆其中的文本节点)
选填 true, 表示克隆后代节点
实例:
<div class="box">
<p>我是通过 HTML 手写的第一个文本节点</p>
<p>我是通过 HTML 手写的第二个文本节点</p>
</div>
<script>
let myDiv = document.querySelector('.box')
let oP = document.querySelector('p')
创建一个元素节点
let oDiv = document.createElement('div')
let oSpan = document.createElement('span')
创建一个文本节点
let oText = document.createTextNode('我是通过 JS 创建出来的文本节点')
将刚创建的文本节点添加到元素节点中
oDiv.appendChild(oText)
向页面中添加一个节点
myDiv.appendChild(oDiv1)
myDiv.appendChild(oSpan1)
(将我们通过 JS 创建的 div 标签,插入到页面的 p 标签的前面)
myDiv.insertBefore(oDIv, oP)
myDiv.insertBefore(oSpan)
删除页面中 p 标签
myDiv.removeChild(oP)
修改页面中的 P 标签(用span 标签替换 p 标签)
myDiv.replaceChild(sPan, oP)
克隆 oP 节点
let cloneP = oP.cloneNode()
let cloneP = oP.cloneNode(true)
</script>
获取元素偏移量
获取元素在页面上相对 参考父级 的 左边 和 上边 的距离
参考父级:
其实就是假设你要给一个元素 ‘绝对定位’,他是根据谁来进行定位,那么这个元素的偏移量参考父级就是谁
获取元素的相对父级
语法: 元素.offsetParent
获取元素距离左边的距离
语法: 元素.offsetLeft
获取元素距离上边的距离
语法: 元素.offsetTop
获取元素尺寸(元素的占地面积)
语法1: 元素.offsetWidth
元素.offsetHeight
语法2: 元素.clientWidth
元素.clientHeight
区别:
offset -> 实际的宽度 / 高度 + padding + border
client -> 实际的宽度 / 高度 + padding