DOM 文档对象模型
DOM 文档对象模型
文章目录
- DOM 文档对象模型
- DOM树和DOM对象
- 获取DOM元素
- 操作元素内容
- 操作元素属性
- 间歇函数
@jarringslee
DOM树和DOM对象
我们通过DOM和BOM用js来操作html。之前所学的alert和prompt属于BOM的操作。
- DOM:文档对象模型 Document Object Model 用来呈现以及与任意HTML或XML文档交互的API,是浏览器提供的一套专门用来操作网页内容的功能
- DOM树(文档树) 将html文档以树状结构直观的表现出来,体现了标签与标签之间的关系。
- DOM对象 浏览器根据html标签自动生成的js对象
- html中标签 对标 js中对象
- 所有标签属性都可以再对象上面找到
- 修改这个对象的属性会自动映射到标签身上
- Document对应最大的html标签
获取DOM元素
html标签、css选择器获取过来就被称为dom对象
查找、获取DOM对象
-
(常用 重点)通过CSS选择器获取DOM元素
-
选择匹配的第一个元素 只选一个!
返回这个css选择器搭配的第一个元素,即一个HTMLElement对象
如果没有找到,返回null
document.querySelector('CSS选择器') //必须加引号(没有引号就成变量了)
const a = document.querySelector('div') //获取第一个div标签 const a = document.querySelector('.box') //获取第一个类为box的标签 const a = document.querySelector('#nav') //获取第一个id为nav的标签 const a = document.querySelector('ul li') //后代:获取第一个ul标签中套着的第一个li标签,不管被套了几层都能被找到 const a = document.querySelector('ul li') //子代:获取第一个ul标签中直接嵌套的第一个li标签,只能是一层父子关系 const a = document.querySelector('ul li:first-child') //获取文档中第一个li标签,且这个li必须由ul包裹。如果不是,则无法获取到任何标签
获取后直接修改css值:
声明对象名.style.属性名 = '属性值'
const a = document.querySelector('#nav') a.style.color = 'red'
-
选择匹配的多个元素:
返回所有符合条件的元素(哪怕只有一个)并集合成一个NodeList 对象集合(伪数组/类数组)。
-
选择所有元素:
const a = document.querySelectorAll('ul li')
获取到一个伪数组(有长度、索引号,但不能用pop()、push()等来操作)。我们要通过遍历的方式修改其中的值。
const list = document.querySelectorAll('ul li');for (let i = 0; i < list.length; i++) {list[i].style.color = 'blue'; } //或者 list.forEach(item => {item.style.color = 'blue'; });
-
-
-
其他方法获取元素
// 根据 id 获取一个元素 document.getElementById('nav');// 根据标签获取所有 div document.getElementsByTagName('div');// 根据类名获取所有 class 为 w 的元素 document.getElementsByClassName('w');
操作元素内容
利用点语法修改元素文本,更换内容
DOM对象都是根据标签生成的,所以操作表前期,本质上就是操作DOM对象。
修改标签元素中的内容主要可以利用下面两种属性:
对象.innerText
属性- (主要使用)
对象.innerHTML
属性
innerText
属性:获取元素文本
//获取元素
const box = document.querySelector('.box')
//直接输出该属性:等价于直接输出元素中的文本
console.log(box.innerText)
//修改文本
box.innerText = '新文本内容'
innerText
可以将文本添加/更新到任意标签位置- 显示纯文本,无法解析标签(不能在引号中写标签)
innerHTML
属性:获取元素文本,解析标签
可以解析标签,其他用法与innerText
相同
box.innerHTML = '<strong>新文本内容</strong>'
随机抽奖原理
//声明抽奖成员数组
const arr = ['ljl', '刘德华', '张学友', '周杰伦', '林俊杰', '郭富城', '黎明', '鹿晗', '黄子韬']
//随机数进行选取
const name1 = Math.floor(Math.random() * arr.length)
//从html中利用id选择器获取填写中奖姓名文本的标签
const one = document.querySelector('#one')
//填入刚才随机选取的成员
one.innerHTML = arr[name1]
//从数组中删除该成员,以便进行下一轮抽选
arr.splice(name1, 1)
操作元素属性
-
操作元素常用属性
直接点语法操作即可,直接通过属性名修改
对象.标签内置属性名 = 标签内置属性值
不涉及到css属性,只有标签自带属性<script>// 1. 获取 img 对应的 DOM 元素const pic = document.querySelector('.pic')// 2. 修改属性pic.src = './images/lion.webp'pic.width = 400;pic.alt = '图片不见了...' </script>
-
控制元素样式属性
-
修改样式 通过修改行内样式
style
属性,实现对样式的动态修改。通过元素节点获得的
style
属性本身的数据类型也是对象,如box.style.color
、box.style.width
分别用来获取元素节点 CSS 样式的color
和width
的值。<div class="box">文本内容</div><script>// 获取 DOM 节点const box = document.querySelector('.box')box.style.color = 'red'box.style.width = '300px'// css 属性的“-”连接符与 JavaScript 的 减运算符冲突,所以要改成 小驼峰 命名法box.style.backgroundColor = 'pink'</script>
含有连接符的属性改为小驼峰命名法 任何标签都有
style
属性,通过style
属性可以动态更改网页标签的样式,如要遇到css
属性中包含字符-
时,要将-
去掉并将其后面的字母改成大写,如background-color
要写成box.style.backgroundColor
获取节点、修改样式可以简写为:
document.querySelector('.box').style.color = 'red'
修改页面整体样式:
document.body.style
可以直接通过
document.body.style
来修改<body>
元素的样式。例如设置网页背景图片:document.body.style.backgroundImage = 'url(./img/bg.jpg)' document.body.style.backgroundColor = 'lightblue'
这个写法等价于:
const body = document.querySelector('body') body.style.backgroundImage = 'url(./img/bg.jpg)'
style
修改的是 行内样式,优先级较高;- 如果你在
<style>
或外部 CSS 中定义了样式,用 JS 改style
会覆盖它; - 你可以通过
console.log(box.style)
看到能直接访问的样式属性(只有行内设置的会显示出来); - 你不能用
style
获取到 CSS 文件里设置的样式值,需要用getComputedStyle()
。
const computedColor = getComputedStyle(box).color
-
操作类名(className) 操作CSS
如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。
另编写一个类选择器,把想要修改的属性写进去,获取节点后直接用
DOM对象名.className
使用后,原有选择器会中的所有属性都会被完全抛弃。
<head><style>.pink {background: pink;color: hotpink;}</style> </head> <body><div class="box">随便一些文本内容</div><script>// 获取 DOM 节点const box = document.querySelector('.box')box.className = 'pink'</script> </body>
注意:
1.由于class是关键字, 所以使用className去代替
2.className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名
-
为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名
old.className = 'old new'
old.classList.add(new)
const box = document.querySelector('.box') box.className = 'box pink' //等价于 box.classList.add('new') //这样做的效果是:class="box new"
<head><style>div {width: 200px;height: 200px;background-color: pink;}.active {width: 300px;height: 300px;background-color: hotpink;margin-left: 100px;}</style> </head><body><div class="one"></div><script>// 1.获取元素// let box = document.querySelector('css选择器')let box = document.querySelector('div')// add() 添加 追加box.classList.add('active')// remove() 移除box.classList.remove('one')// 切换类box.classList.toggle('one')</script> </body>
classList的常用方法小总结
element.classList.add('className') // 添加类 element.classList.remove('className') // 移除类 element.classList.toggle('className') // 有则删除,无则添加 element.classList.contains('className') // 判断是否含有该类,返回 true/false
-
-
操作表单元素属性
-
获取表单文本框中用户输入的值:用的是value属性
const text = document.querySelector('input') console.log(text.value)
-
用户输入密码时点击按钮,切换可见与不可见
获取元素后,修改元素的type值即可
const text = document.querySelector('input') input.type = 'text' input.type = 'password'
-
控制选项框的勾选
获取元素后,可利用布尔变量修改元素的checked值。
checkbox复选框的自带属性checked中“checked”代表已勾选,不写这个属性代表未勾选。
由于属性名与属性值相同,书写时可以简写为一个单词。
<input type="checkbox" name="" id="" checked> //等价于 <input type="checkbox" name="" id="" checked="checked">
在js中,checked属性默认只接受布尔值。选中后,true即为已选中状态。
const ipt = document.querySelector('input') ipt.checked = true
如果这里带了单引号
'true'
,那么也会被判定为真。因为布尔变量下的字符串,除了空字符串,都会被隐式转换为真。即这里只要输入任意非空字符串都会被判定为真。
-
表单元素中接受布尔值的属性(不添加就是默认没有该效果)
- disabled禁用按钮(默认为不禁用)
- checked勾选选择框(默认为不勾选)
- selected默认展示该选项 (默认为不展示)
添加就有效果,移除就没有效果,因为属性名和属性值相同所以一般都简写为一个单词。这些属性在js中一律用布尔值表示。
-
-
**自定义属性 **
标准属性: 标签天生自带的属性 比如class id title等, 可以直接使用点语法操作比如: disabled、checked、selected
自定义属性:
在html5中推出来了专门的data-自定义属性
在标签上一律以data-开头,在DOM对象上一律以dataset对象方式获取
用于给元素自定义一些属性。
<div data-id="1"> 自定义属性 </div><script>// 1. 获取元素let div = document.querySelector('div')// 2. 获取自定义属性值console.log(div.dataset.id) </script>
<div class="card" data-id="101" data-name="手机" data-price="2999"></div><script> const card = document.querySelector('.card') console.log(card.dataset.id) // "101" console.log(card.dataset.name) // "手机" console.log(card.dataset.price) // "2999" </script> //dataset.属性名,注意:data-后的名字中有 - 时,要改成小驼峰命名 //例如:data-user-id 对应 JS 中访问为 dataset.userId
间歇函数
setInterval
是 JavaScript 中内置的函数,它的作用是间隔固定的时间自动重复执行另一个函数,也叫定时器函数。
-
开启定时器
setInterval(调用函数名(不能带括号), 间隔时间(毫秒)) //等价于 setInterval( () => { /* 函数内容 */ }, 时间间隔(毫秒) ); //等价于 setInterval( function() { /* 函数内容 */ }, 时间间隔(毫秒) );
<script>// 1. 定义一个普通函数function repeat() {console.log('不知疲倦的执行下去....')}// 2. 使用 setInterval 调用 repeat 函数// 间隔 1000 毫秒,重复调用 repeat setInterval(repeat, 1000) </script>
-
关闭定时器 clearInterval(变量名)
let 变量名 = setInterval(函数, 间隔时间) //持续一定时间后关闭函数: setTimeout(function () {clearInterval(变量名)}, 函数持续时间) //也可以用if语句触发某一条件来关闭函数等。
DOM小练习 随机轮播图(自动版)
因为这里还没有到事件监听,所以还暂时没有手动换图操作。手动版就是通过刷新来随机展示,设置数组随机数然后填进模版即可。自动版就用到了最后学的间歇函数,在这里只进行了简单的使用,注意如果想调用之前函数中的数据,可以把这个数据拉出函数放到前面先声明一下(注意可能要改成let)。主要考察点就是拉取DOM对象,需要注意的是写法规范,点操作、样式操作等都要仔细检查。
<!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>轮播图点击切换</title><style>* {box-sizing: border-box;}.slider {width: 560px;height: 400px;overflow: hidden;}.slider-wrapper {width: 100%;height: 320px;}.slider-wrapper img {width: 100%;height: 100%;display: block;}.slider-footer {height: 80px;background-color: rgb(100, 67, 68);padding: 12px 12px 0 12px;position: relative;}.slider-footer .toggle {position: absolute;right: 0;top: 12px;display: flex;}.slider-footer .toggle button {margin-right: 12px;width: 28px;height: 28px;appearance: none;border: none;background: rgba(255, 255, 255, 0.1);color: #fff;border-radius: 4px;cursor: pointer;}.slider-footer .toggle button:hover {background: rgba(255, 255, 255, 0.2);}.slider-footer p {margin: 0;color: #fff;font-size: 18px;margin-bottom: 10px;}.slider-indicator {margin: 0;padding: 0;list-style: none;display: flex;align-items: center;}.slider-indicator li {width: 8px;height: 8px;margin: 4px;border-radius: 50%;background: #fff;opacity: 0.4;cursor: pointer;}.slider-indicator li.active {width: 12px;height: 12px;opacity: 1;}</style>
</head><body><div class="slider"><div class="slider-wrapper"><img src="./images/slider01.jpg" alt="" /></div><div class="slider-footer"><p>对人类来说会不会太超前了?</p><ul class="slider-indicator"><li class="active"></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><div class="toggle"><button class="prev"><</button><button class="next">></button></div></div></div><script>// 1. 初始数据const sliderData = [{ url: './images/slider01.jpg', title: '凤凰传奇陪你过大年', color: 'rgb(100, 67, 68)' },{ url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },{ url: './images/slider03.jpg', title: '对人类来说会不会太超前了? ', color: 'rgb(36, 31, 33)' },{ url: './images/slider04.jpg', title: '真正的jo厨出现了!', color: 'rgb(139, 98, 66)' },{ url: './images/slider05.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(67, 90, 92)' },{ url: './images/slider06.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(166, 131, 143)' },{ url: './images/slider07.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(53, 29, 25)' },{ url: './images/slider08.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(99, 72, 114)' },]// 1. 获取元素 const img = document.querySelector('.slider-wrapper img')const p = document.querySelector('.slider-footer p')let i = 0 // 信号量 控制图片的张数// 2. 开启定时器// console.log(sliderData[i]) 拿到对应的对象啦const gogogo = setInterval(function () {i++// 无缝衔接位置 一共八张图片,到了最后一张就是 8, 数组的长度就是 8if (i >= sliderData.length) i = 0// 更换图片路径 img.src = sliderData[i].url// 把字写到 p里面p.innerHTML = sliderData[i].title// 小圆点// 先删除以前的activedocument.querySelector('.slider-indicator .active').classList.remove('active')// // 只让当前li添加activedocument.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')}, 1000)setTimeout(function () {clearInterval(gogogo)}, 10000)</script>
</body></html>