DOM的基本概念
DOM: 文档对象模型
其实就是操作html 中标签的一些能力
比如: 获取一个元素
移除一个元素
创建一个元素
向页面添加一个元素
给元素绑定一些事件
获取元素的属性
给元素添加一些css样式
...
DOM的核心就是 document 对象
document 对象就是 JS内置的一个对象, 里边存储着专门用来操作元素的各种方法
获取元素
获取非常规元素
document.documentElement -> html标签
document.head -> head标签
document.body -> body标签
//1.html 标签
console.log(document.documentElement)
//2. head标签
console.log(document.head)
//3. body标签
console.log(document.body)
获取常规元素
1. 通过 ID 名获取标签
语法: document.getElementById('ID名')
2. 通过 class 名获取标签
语法: document.getElementByClassName('class名') 注意: Element有s 因为class名不唯一
因为页面中可能会有多个元素的class相同, 所以获取到的是一组元素
获取到后会把元素放在一个长得很像数组一样的 数据结构内,但他并不是数组, 我们管这种数据结构 叫做 伪数组
伪数组: 长得很像数组, 也是通过索引排列, 但是没有数组的方法
3. 通过标签名获取
语法: document.getElementsByTagName('标签名')
注意: 获取到的也是一个长得很像数组一样的数据结构, 其实就是获取到了一个伪数组, 想要准确的获取到标签元素, 我们需要通过索引来帮助我们拿到
4. 按照选择器的形式来获取元素
4.1. querySelector,这个方法允许我们像写 css 的时候 的选择器一样获取标签
注意: 这个方法只能获取到一个元素, 就是满足条件的第一个元素
语法: document.querySelector('选择器')
4.2. querySelectorAll, 该方法与querySelector 选择器类似, 只不过会将所有满足条件的元素都获取到, 也是放在一个伪数组
//1 获取到页面中 ID名为box的标签
var box = document.getElementById('box') //获取到页面中 ID为box 的标签
console.log(box)
//2 获取到页面中 class名为box_cla的标签
var box_cla = document.getElementsByClassName('box_cla') //获取到页面中 class名为box_cla 的标签
console.log(box_cla)
console.log(box_cla[0])
console.log(box_cla[1])
console.log(box_cla[2])
//直接打印和索引打印控制台效果不同
//3 获取到页面中 标签名为div的标签
var divs = document.getElementsByTagName('div')
console.log(divs)//输出所有标签名为div的
console.log(divs[0])//输出指定的
//4.1 按照选择器的形式获取标签
var box2 = document.querySelector('.box_cla')
console.log(box2)
var box3 = document.querySelector('div')
console.log(box3)
//4.2
var box4 = document.querySelectorAll('.box_cla')
console.log(box4)
var box5 = document.querySelectorAll('div')
console.log(box5)
操作DOM属性
我们获取到元素以后,可以直接操作DOM的属性, 然后直接展示在页面
1. innerHTML
获取元素内部的HTML结构
我们也可以直接给这个属性重新赋值, 达到修改页面的效果
2. innerText
获取到元素内部的文本(只能获取文本,不能获取HTML标签)
var oDiv = document.querySelector('#box')
console.log(oDiv)
console.log(oDiv.innerHTML) //<p><span>大家早上好!!!</span></p>
oDiv.innerHTML = '<p><span>大家早上好!!!</span></p>' // 控制台不显示,但是页面显示文本
console.log(oDiv.innerText) //页面和控制台都显示 大家早上好!!!
oDiv.innerText = '<p><span>大家早上好!!!</span></p>'
// 页面显示 <p><span>大家早上好!!!</span></p>
操作元素属性
获取元素的某些特性
-
语法: 元素.getAttribute('要查询的属性名') -
返回值: 查询到 属性时返回对应的属性值, 没有查询到时 直接返回null修改(新增)元素的某些特性
-
语法: 元素.setAttribute('对应的属性名', '对应的属性值') -
注意: 如果元素没有对应的属性名,那么相当于是新增的一个属性删除元素的某些特性
-
语法:removeAttribute('要删除的属性名')
<div class="box" a="100"></div>
// 0. 获取元素
//var oDiv = document.querySelector('.box')
var oDiv = document.getElementsByClassName('box')[0]//注意下标的写法
// console.log(oDiv)
//1. 获取
console.log(oDiv.getAttribute('a'))
console.log(oDiv.getAttribute('class'))
console.log(oDiv.getAttribute('b')) //null
//2. 修改/新增
oDiv.setAttribute('a', 'GX999')
oDiv.setAttribute('class', 'bigbox')
oDiv.setAttribute('b', 'qwer')
console.log(oDiv.getAttribute('a'))
//3. 删除
oDiv.removeAttribute('a')
oDiv.removeAttribute('class')
h5 自定义属性
data- 表示该属性是一个自定义属性
data- 后面的内容才是属性名, 当前案例中属性名为a, 不是data-a
= 后的内容是属性值
每一个 元素/DOM节点 天生自带一个属性,叫做dataset,是一个类似对象的数据结构
<div data-a="100"></div>
// 0. 获取标签
var oDiv = document.querySelector('div')
// 1. 访问元素的dataset 属性 =查询
console.log(oDiv.dataset.a) //100
// 2.增加一个h5 自定义属性
oDiv.dataset.age = 18 //新增
console.log(oDiv.dataset.age) //18
oDiv.dataset.a = 'gx666' //修改
// 3. 删除
delete oDiv.dataset.a
元素样式
获取元素样式
语法: 元素.style.某个属性
注意:
1. 我们也可以给这个语法重新赋值, 达到修改 元素样式的效果
2. 这种语法获取到的元素样式,只能获取到 行内样式
// 0. 获取元素
var oDiv = document.querySelector('.box')
// 1. 获取元素样式
//只能获取行内
console.log(oDiv.style.width)
console.log(oDiv.style.height)
console.log(oDiv.style['background-color'])//中括号语法
console.log(oDiv.style.backgroundColor)
// 2. 设置元素样式
//直接添加到行内
oDiv.style.width = 666 + 'px'
oDiv.style.backgroundColor = 'green'
获取非行内样式
语法:window.getComputedStyle(元素).要查询的css属性
注意: 这种方式获取到的属性是只读的
只读:能获取到,但是不允许修改
console.log(window.getComputedStyle(oDiv).width)
console.log(window.getComputedStyle(oDiv).backgroundColor)
window.getComputedStyle(oDiv).width = 800 + 'px' //不允许修改,会有报错
元素类名
获取元素类名
1. className
专门用来操作元素的类名
语法: 元素.className
我们也可以给他重新赋值, 来达到修改元素的类名,如果元素有多个类名,会全部删除变为新类名
console.log(oDiv.className)
oDiv.className = 'qwer'
2. classList(更推荐)
获取
新增
删除
//2.1 获取
console.log(oDiv.classList)
//2.2 新增
oDiv.classList.add('qwer')
//2.3 删除
oDiv.classList.remove('new_box')
DOM对象(节点node)
页面中的标签,我们通过JS获取到以后,就把这个对象叫做 DOM对象(DOM节点)
DOM节点分类
-
一般来说我们分为三个大类 元素节点(标签) / 文本节点(标签内的文字) / 属性节点(标签 上 的属性)
元素节点 通过getElementBy... 获取到的都是元素节点(页面中的标签) 属性节点 通过getAttribute 获取到的是属性节点(与元素节点是父子关系) 文本节点 通过innerText 获取到的就是元素的文本节点(内容,空格,回车等)
获取子节点
- 获取某一节点下所有的 子一级 节点, 获取到的是一个伪数组
语法:元素.childNodes
- 获取某一节点下 所有的 子一级 元素节点, 获取到的是一个伪数组
语法:元素.children
- 获取某一节点下子一级的 第一个节点(不区分节点类型)
语法:元素.firstChild
- 获取某一节点下子一级的 最后一个节点(不区分节点类型)
语法:元素.lastChild
- 获取某一节点下子一级的 第一个元素节点
语法:元素.firstElementChild
- 获取某一节点下子一级的 最后一个元素节点
语法:元素.lastElementChild
// 0.获取元素
var oDiv = document.querySelector('div')
// 1. childNodes
console.log(oDiv.childNodes)
NodeList(7) [text, p, text, span, text, h1, text]
// 2.children
console.log(oDiv.children) // HTMLCollection(3) [p, span, h1],这里只有 div 内部的标签
// 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>
获取兄弟节点
-
获取对应的 下一个兄弟节点
语法:
元素.nextSibling -
获取对应的 上一个兄弟节点
语法:
元素.previousSibling -
获取对应的 下一个兄弟元素节点
语法:
元素.nextElementSibling -
获取对应的 上一个兄弟元素节点
语法:
元素.previousElementSibling
//0. 获取节点
var oSpan = document.querySelector('span')
//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>
获取父节点与属性节点
- 父节点
- 语法:
元素.parentNode
- 获取元素的所有属性节点
- 语法:
元素.attributes
//0.获取节点
var oH = document.querySelector('h1')
//1. parentNode
console.log(oH.parentNode)
//2. attributes
console.log(oH.attributes) //NamedNodeMap {0: id, 1: class, 2: test, 3: num, id: id, class: class, test: test, num: num, length: 4}
节点属性
1. nodeType 节点类型
节点中的一个属性 nodeType 能够区分当前节点是什么类型
1 -> 元素节点
2 -> 属性节点
3 -> 文本节点
2. nodeName 节点名称
元素节点 -> 大写的标签名
属性节点 -> text (属性)
文本节点 -> #text
3. nodeValue 节点的值
元素节点 ->没有nodeValue 也就会输出 null
属性节点 ->对应的属性值
文本节点 ->对应的文本内容
<ul text="我是UL的一个属性">
<li>你好</li>
</ul>
//0. 获取元素
var oUl = document.querySelector('ul')
//1. 元素节点
var eleNode = oUl.firstElementChild
//2. 属性节点
var attrNode = oUl.attributes[0]
//3. 文本节点
var textNode = oUl.firstChild
//1. nodeType
console.log('元素节点: ', eleNode.nodeType) // 1
console.log('属性节点: ', attrNode.nodeType) // 2
console.log('文本节点: ', textNode.nodeType) // 3
//2. nodeName
console.log('元素节点: ', eleNode.nodeName) // 元素节点: LI
console.log('属性节点: ', attrNode.nodeName) // 属性节点: text
console.log('文本节点: ', textNode.nodeName) // 文本节点: #text
//3. nodeValue
console.log('元素节点: ', eleNode.nodeValue) // 元素节点: null
console.log('属性节点: ', attrNode.nodeValue) // 属性节点: 我是UL的一个属性
console.log('文本节点: ', textNode.nodeValue) // 文本节点:
操纵 DOM 节点
常规意义上的操作 DOM 节点无非就是 增删改查(CRUD)
注意, 在增加节点前, 我们应该先有一个节点, 所以应该是
1. 创建 2. 向页面中增加一个节点 3. 删除页面中的某一个节点 4. 修改页面中的某一个节点 5. 获取页面中的某一个节点
创建节点
- createElement 创建一个元素节点
var oDiv = document.createElement('div')
console.log(oDiv) // <div></div>
- createTextNode 创建一个文本节点
var oDiv = document.createTextNode('我是一个文本节点~啦啦啦啦啦')
console.log(oDiv) // 我是一个文本节点~啦啦啦啦啦
向页面中加入一个节点
- appendChild: 向一个元素节点的末尾追加一个节点
- 语法:
父节点.appendChild(要插入的子节点)
- 语法:
var oDiv = document.createElement('div')
var oText = document.createTextNode('我是一个文本节点~啦啦啦啦啦')
// 向 oDiv 中追加一个文本节点
oDiv.appendChild(oText)
console.log(oDiv)
- insertBefore: 向一个元素节点前插入一个节点
- 语法:
父节点.insertBefore(要插入的节点, 插入在哪一个节点的前面) - 注意点: insertBefore 的第二个参数不是可选项是必选项, 传递正常节点时代表:
插入在哪一个节点的前面, 如果传递的是 null, 则表示插入到父节点的 末尾
- 语法:
<div>
<p>我是一个 p 标签</p>
</div>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
// 创建一个元素节点
var oSpan = document.createElement('span')
// 将这个元素节点添加到 div 下的 p 的前面
oDiv.insertBefore(oSpan, oP)
console.log(oDiv)
/**
* <div>
* <span></span>
* <p>我是一个 p 标签</p>
* </div>
*/
删除页面中的某一个节点
- removeChild: 移出某一节点下的某一个节点
- 语法:
父节点.removeChild(要移除的子节点)
- 语法:
<div>
<p>我是一个 p 标签</p>
</div>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
oDiv.removeChild(oP)
console.log(oDiv) // <div></div>
修改页面中的某一个节点
- replaceChild: 将页面中的某一个节点替换掉
- 语法:
父节点.replaceChild(新节点, 旧节点)
- 语法:
<div>
<p>我是一个 p 标签</p>
</div>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
// 创建一个 span 节点
var oSpan = document.createElement('span')
// 向 span 元素中加点文字
oSpan.innerHTML = '我是新创建的 span 标签'
// 用创建的 span 标签替换原先 div 下的 p 标签
oDiv.replaceChild(oSpan, oP)
console.log(oDiv)
/*
<div>
<span>我是新创建的 span 标签</span>
</div>
*/
克隆页面中的某一个节点
- cloneNode: 把该节点复制一份一摸一样的
- 语法:
节点.cloneNode(参数)- 默认是false, 表示不克隆后代节点
- 选填是 true, 表示克隆后代节点
- 语法:
<div>
<p>我是一个 p 标签</p>
</div>
var oDiv = document.querySelector('div')
var oP = oDiv.querySelector('p')
// 克隆节点
var cloneDiv = oDiv.cloneNode()
var cloneDiv1 = oDiv.cloneNode(true)
console.log(cloneDiv)
console.log(cloneDiv1)
获取元素的非行内样式
- 操作 DOM 的时候 经常会操作元素的 CSS 样式, 所以我们免不了需要获取元素的样式
- 元素.style.xxx 的方式也只能获取到元素的 行内样式
div {
width: 100px;
}
<div style="height: 100px"></div>
var oDiv = document.querySelector('div')
console.log(oDiv.style.height) // 100px
console.log(oDiv.style.width) // ''
- 所以我们要想获取元素的 非行内样式, 就需要使用
getComputedStyle 和 currentStyle - 这两个方法作用是一样的, 只不过一个是在 非 IE 浏览器, 一个在 IE 浏览器
getComputedStyle (非IE使用)
- 语法:
window.getComputedStyle(元素).要获取的属性
div {
width: 100px;
}
<div style="height: 100px"></div>
var oDiv = document.querySelector('div')
console.log(window.getComputedSTYLE(oDiv).width) // 100px
console.log(window.getComputedSTYLE(oDiv).height) // 100px
currentStyle (IE使用)
- 语法:
元素.currentStyle.要获取的属性
div {
width: 100px;
}
<div style="height: 100px"></div>
var oDiv = document.querySelector('div')
console.log(oDiv.currentStyle.width) // 100px
console.log(oDiv.currentStyle.height) // 100px
获取元素偏移量
就是元素在页面上相对于参考父级的左边和上边的距离
offsetParent
- 获取元素的偏移量参考父级
- 其实就是假设你要给一个元素 绝对定位 的时候
- 它是根据谁来进行定位的, 那么这个元素的偏移量参考父级就是谁
offsetLeft / offsetTop
- 获取的事元素左边的偏移量和上边的偏移量
- offsetLeft 该元素相对于参考父级的左侧偏移量
- offsetTop 该元素相对于参考父级的上侧偏移量
获取元素尺寸
获取元素的占地面积
offsetWidth 和 offsetHeight
- offsetWidth: 获取元素内容 + padding + border 的宽度
- offsetHeight: 获取元素内容 + padding + border 的高度
clientWidth 和 clientHeight
- clientWidth 获取元素内容 + padding 的宽度
- clientHeight 获取元素内容 + padding 的高度
注意
- 获取到的尺寸是没有单位的数字
- 当元素在页面中不占位置的时候, 获取到的是 0
display: none元素在页面不占位visibility: hidden元素在页面占位
获取浏览器窗口尺寸
可视区域的尺寸
- document.documentElement.clientWidth: 浏览器可视窗口的宽度
- document.documentElement.clientHeight: 浏览器可视窗口的高度