DOM
DOM的基本概念
DOM: 文档对象模型
其实就是操作html中标签的一些能力
比如:
获取一个元素(标签)
移除一个元素
创建一个元素
向页面添加一个元素
给元素绑定一些事件
.....
DoN的核心就是document对象
document对象是Js内置的一个对象,里边存储着专门用来操作元素的各种方法
DOM:页面中的标签,我们通过JS获取到以后,就把这个对象叫做 DON 对象(DOM节点)
DOM的一些操作
1.获取元素
1-1. 获取非常规元素
document.documentElement -> 获取 html 标签
document.head -> 获取 head 标签
document.body -> 获取 body 标签
1-2. 获取常规元素
(1).同过 ID 名获取标签
语法: document.getElementById('ID 名')
(2).通过 class 类名获取标签
语法: document.getElementsByClassName('class 类名')
注意:因为页面中可能会有多个元素的class相同,所以获取到的是一组元素,获取到后会把元组放到一个很想数组的元素结构中,
但不是真正的数组,我们称之为 伪数组
伪数组: 长得很像数组,也是通过索引排列,但是没有数组的方法
(3).通过标签名来获取
语法:document.getElementsByTagName('标签名')
注意: 获取到的也是一个伪数组,想要准确的获取到标签元素,我们需要通过索引来帮助我们拿到
*(4).按照选择器的形式来获取元素
A. querySelector
这个方法允许我们像写css的时候的选择器一样获取标签
注意:这个方法只能获取到一个元素,就是满足条件的第一个元素
语法:document.querySelector('类名')
B. querySelectorAll
该方法与querySelect 选择器类似,只不过会将所有满足条件的元素都获取到,获取到的也是一个伪数组
语法:document.querySelectorAll('标签名')
操作属性
我们获取到元素以后,可以直接操作DOM的属性,然后直接把效果展示在页面
1.innerHTML
获取元素内部的HTML解构
我们也可以直接给这个属性重新赋值,达到修改页面的效果
2.innerText
获取元素内部的文本(只能获取到文本,获取不到html标签)
我们也可以直接给这个属性重新赋值,达到修改页面的效果
元素属性
1.获取(查询)元素的一些属性
语法:元素.getAttribute('要查询的属性名')
返回值:查询到返回属性对应的值
查询不到返回null
2.修改元素的某些属性
语法:元素.setAttribute('对应的属性名','对应的属性值')
注意:如果元素没有对应的属性名,那么相当于是新增一个属性
3.删除元素的某些属性
语法:元素.removeAttribute('要删除的属性名')
h5 自定义属性
h5 自定义属性
data- 表示该属性是一个自定义属性
data- 后边的内容才是属性名,当前案例中属性名为a
= 后面的内容是属性值
每一个 元素 / DOM节点
天生自带一个属性,叫做dataset,是一个类似对象的数据结构
案例:
<body>
<div data-a="100"></div>
<script>
//0.获取标签
var oDiv = document.querySelector('div')
//1.访问元素的 dataset 属性
console.log(oDiv.dataset.a) //打印100
//2.增加一个h5自定义属性
oDiv.dataset.age = 18
//标签中没有这个自定义属性,所以是新增
oDiv.dataset.a = 'QF018'
//标签中有这个自定义属性,所以是修改
//3.删除
delete oDiv.dataset.a
</script>
</body>
获取元素样式
1.获取行内元素样式
语法:元素.style.某个属性
注意:
我们也可以给这个语法重新赋值,达到修改元素样式的效果(修改的是行内的样式)
这种语法获取到的元素样式,只能获取到行内样式
2.获取非行内样式
语法: window.getComputedStyle(元素).要查询的css属性
注意:这种方式获取到的属性是只读的
只读:能获取到,但是不允许修改
获取元素偏移量
- 获取元素在页面上相对于
父级 左边 和 上面的 距离, 参考父级: - 其实就是假设你要给一个元素 '绝对定位' ,他就是根据谁来进行定位,那么这个元素的偏移量参考父级就是谁
1.语法: 元素.offsetParent 获取元素的相对父级
2.语法:元素.offsetLeft 获取元素距离父级元素左边的距离
3.语法:元素.offsetTop 获取元素距离父级元素顶部的距离
<div class="box1">
<div class="box2"></div>
</div>
* {
padding: 0;
margin: 0;
}
.box1 {
width: 400px;
height: 400px;
background-color: pink;
position: relative;
top: 20px;
left: 20px;
}
.box2 {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute;
left: 100px;
top: 200px;
}
//0.获取元素
var box2 = document.querySelector('.box2')
//1.获取相对父级
console.log(box2.offsetParent)
//<div class="box1"><div class="box2></div></div>
//2.offsetLeft
console.log(box2.offsetLeft)// 100
//3.offsetTop
console.log(box2.offsetTop)// 200
获取元素(浏览器窗口)尺寸
元素的占地面积
1.语法1:
元素.offsetWidth 元素宽度
元素.offsetHeight 元素高度
2.语法2:
元素.clientWidth 元素宽度
元素.clientHeight 元素高度
两者区别:
offset XXX -> 实际的宽度/高度 + padding + border
client XXX -> 实际的宽度/高度 + padding
获取浏览器窗口尺寸
-
window.innerXXX---> 计算时候会包含浏览器滚动条 -
document.documentElement.clientXXX---> 计算的时候不会计算滚动条(只计算浏览器的可视区域)
获取元素 类名
1. className
专门用来操作元素的 类名
语法:元素.className
我们也可以给他重新赋值。来达到修改元素的类名
注意:修改时会修改所有类名
2. classList
获取
语法:元素.classList
新增
语法:元素.classList.add('新增的类名')
删除
语法:元素.classList.remove('要删除的类名')
DOM 节点
节点类型
一般来说,分为三类
- 元素节点(标签)
通过 getELementBy...获取到的都是元素节点 - 文本节点(标签里的文字)
通过 innerText 获取到的就是元素的文本节点 - 属性节点(标签上的属性)
通过 getAttribute 获取到的都是属性节点
获取节点
- 获取某一节点下的所有的
子一级节点 获取到的是一个伪数组
语法 : 元素.childNodes
- 获取某一节点下的所有的
子一级元素节点获取到的是一个伪数组里面只有标签
语法 : 元素.children
- 获取某一节点下的
子一级 第一个节点
语法:元素.firstChild
- 获取某一节点下的
子一级 最后一个节点
语法:元素.lastChild
- 获取某一节点下的
子一级 第一个元素节点
语法:元素.firstElementChild
- 获取某一节点下的
子一级 最后一个元素节点
语法:元素.lastElementChild
<div>
<p>你好</p>
<span>测试文本呢</span>
<h1>js 最棒</h1>
</div>
<script>
// 0.获取元紊
var oDiv = document.querySelector('div')
// 1. childNodes
console.log(oDiv.childNodes) //[text, p, text, span, text, h1, text]
/**
* 拿到的是一个伪数组,里边有7个节点本
* [0]: text 从<div>一直到<p〉中间有一个换行和一堆空格―这是一个文本节点
* [1]: p 这个就是p标签,他是第二个节点,这是一个元素节点
* [2]: text 从</p>一直到<span>中间有一个换行和一堆空格﹐这是一个文本节点
*
*/
//2.children
console.log(oDiv.children) // [p, span, h1]
//3.firstChild
console.log(oDiv.firstChild) //#text
//4.lastChild
console.log(oDiv.lastChild) //#text
//5.firstElementChild
console.log(oDiv.firstElementChild) //<p>你好</p>
//6.lastElementChild
console.log(oDiv.lastElementChild) //<h1>js 最棒</h1>
</script>
获取兄弟节点
1.获取对应的 下一个兄弟节点
语法:元素.nextSibling
2.获取对应的 上一个兄弟节点
语法:元素.previousSibling
3.获取对应的 下一个兄弟的元素节点
语法:元素.nextElementSibling
4.获取对应的 上一个兄弟的 元素节点
语法:元素.previousElementSibling
<div>
<p>你好</p>
<span>测试文本呢</span>
<h1>js 最棒</h1>
</div>
<script>
//0.获取元素
var oSpan = document.querySelector( 'span ')
////[text, p, text, span, text, h1, text]
//1.nextSibling
console.log(oSpan.nextSibling) //#text
//2.previousSibling
console.log(oSpan.previousSibling) //#text
//3.nextElementSibling
console.log(oSpan.nextElementSibling) //<h1>js 最棒</h1>
//4.previousElementSibling
console.log(oSpan.previousElementSibling) //<p>你好</p>
</script>
获取父节点
1.父节点
语法 : 元素.parentNode
2.获取元素的所有属性节点
语法 : 元素.attributes
<p>你好</p>
<span>测试文本呢</span>
<h1 id="h1_box" class="h1_box_cla" test="QF001" num="100">js 最棒</h1>
<script>
//0。获取节点
var oH = document.querySelector('h1')
//1. parentNode
console.log(oH.parentNode)
//2.attributes
console.log(oH.attributes)
</script>
节点属性
1.nodeType
- 节点中的一个属性 nodeType 能够区分当前节点是
什么类型-
1 -> 元素节点 -
2 -> 属性节点 -
3 -> 文本节点
-
2.nodeName 节点名称
-
元素节点 -> 大写的标签名 如:DIV,P UL -
属性节点 -> text (属性名) -
文本节点 -> #text
- nodeValue 节点的值
-
元素节点 -> 没有 nodeValue, 会输出null -
属性节点 -> 对应的属性值 -
文本节点 -> 对应的文本
<ul text="我是ul的一个属性">
<li>你好</li>
</ul>
<script>
//0.获取元素
var oUl = document.querySelector('ul')
//1.元素节点
var eleNode = oUl.firstElementChild
//2.属性节点
var attNode = oUl.attributes[0]
//文本节点
var textNode = oUl.firstChild
console.log('元素节点: ', eleNode.nodeType)// 1
console.log('属性节点: ', attNode.nodeType)// 2
console.log('文本节点: ', textNode.nodeType)// 3
console.log('元素节点: ', eleNode.nodeName)// LI
console.log('属性节点: ', attNode.nodeName)// text
console.log('文本节点: ', textNode.nodeName)// #text
console.log('元素节点: ', eleNode.nodeValue)// null
console.log('属性节点: ', attNode.nodeValue)// 我是ul的一个属性
console.log('文本节点: ', textNode.nodeValue)// 啥也没有
</script>
操作DOM节点(增删改查)
增删改查
- 向页面增加一个节点,首先,你需要有一个节点
1.在 JS 中创建一个节点
语法 : document.createElement('要创建的标签名‘)
2.向页面增加一个节点
语法1:元素.appendChild(要添加的节点)
作用:向元素的末尾添加一个节点
语法2:元素.insertBefore(要插入的节点,插入到哪个节点的前面)
* 注意 : 两个参数都是必填
二个参数传递正常节点时,代表插入到这个节点的前面
第二个参数传递的是null 时,表示插入到“元素”的末尾
3.移除页面某一个节点
语法1:父节点.removeChild('要删除的子节点')
语法2:节点.remove() 直接删除对应的节点
4.修改页面的某一个节点
- 将页面中的某一个节点进行 替换
语法:父节点.replaceChild('新节点','旧节点/要被修改的节点')
5.获取页面的某一个节点
- 同之前获取元素的方法
6.克隆一个节点 (复制一个一模一样的标签)
语法:节点.cloneNode(参数)
参数 : 默认是false,表示不克隆后代节点
选填是true,表示克隆后代节点
经典案例 : 密码可视化
密码:<input type="password">
<button id="btn">这是一个眼睛图标</button>
<script>
/**
* 密码可视化
*
* 1.监听btn是否被监听
* 语法:元素.onclick = function (){}
* 2.点击时判断 input 的 type 属性
* 如果type == password -> 重新赋值为text
* 如果type === text -> 重新赋值为password
*/
//0.获取标签
var btn = document.querySelector('button')
var inp = document.querySelector('input')
//1.监听btn
btn.onclick = function(){
//2.点击时判断type
//方法1
// if(inp.getAttribute('type') === 'password'){
// inp.setAttribute('type','text')
// }else if(inp.getAttribute('type') === 'text'){
// inp.setAttribute('type','password')
// }
//方法2
if(inp.type === 'password'){
inp.type = 'text'
}else if(inp.type === 'text'){
inp.type = 'password'
}
}
</script>