主题
2-2样式操作及案例(一)
本页对应 第二章WebAPIs,共 5 段视频,约 32 分钟。
学习目标
- 能获取指定元素,并对其常用属性(如
src、href、title、alt)完成读取、修改、新增和删除操作。 - 能使用
Math.random()与Math.floor()从图片地址数组中随机取值,并修改图片元素的src实现刷新随机显示图片。 - 能通过
element.style.属性名修改元素内联样式,正确使用小驼峰命名并补充必要 CSS 单位。 - 能获取
body元素,并使用style.backgroundImage配合url()与模板字符串实现随机背景图片切换。 - 能通过
className为元素添加或替换类名以修改样式,并说明原类名被覆盖的问题及保留多个类名的写法。 - 能使用
setInterval创建间隔定时器,并按指定周期执行回调,能根据需求清除定时器。
知识点
操作元素内容:innerText 与 innerHTML
为什么需要:DOM 对象可以操作页面标签,本质上就是操作 DOM 对象(增删改查)。要改标签里显示的文字,就要用 innerText 或 innerHTML。怎么想:先获取元素对象,再读或写它的内容属性;查是直接打印,改/增是赋新值,删是赋空字符串。怎么做:
html
<script>
// 操作DOM元素内容
// 1. 对象.innerText 增删改查
// 1.1 查
console.log(box.innerText) // 古丽扎娜
// 1.2 改
box.innerText = '迪丽热巴'
// 1.3 增
const box1 = document.querySelector('.box1')
console.log(box1)
box1.innerText = '佟丽丫丫'
// 1.4 删 给空字符串可以删除内容
box.innerText = ''
box1.innerText = ''
</script>innerText 将文本内容添加/更新到任意标签位置,文本中包含的标签不会被解析。innerHTML 同样能添加/更新内容,但文本中包含的标签会被解析:
html
<script>
// 2. 对象.innerHTML 会解析标签
box.innerHTML = '<strong>迪丽热巴</strong>'
</script>易错点:如果文本内容中包含 html 标签时推荐使用 innerHTML,否则建议使用 innerText;删除内容不是删元素,而是把内容赋成空字符串。
年会抽奖案例:随机抽取且不重复
为什么需要:练习用 innerText 把随机名字写进 span,并用数组删除避免重复中奖。怎么想:先用 Math.random() 取数组下标,把名字写入对应盒子,再用 splice(随机数,1) 删除刚抽出的名字。怎么做:
html
<!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>
.wrapper {
width: 840px;
height: 420px;
background: url(./images/bg01.jpg) no-repeat center / cover;
padding: 100px 250px;
box-sizing: border-box;
}
.wrapper span {
color: #b10e0d;
}
</style>
</head>
<body>
<div class="wrapper">
<strong>年会抽奖</strong>
<h1>一等奖:<span class="one">???</span></h1>
<h3>二等奖:<span class="two">???</span></h3>
<h5>三等奖:<span class="three">???</span></h5>
</div>
<script>
// 数组
const arr = ['迪丽热巴', '古丽扎娜', '佟丽丫丫', '马尔扎哈']
// 1. 一等奖的做法
// 1.1 利用随机数选取数组中的名字
const random = Math.floor(Math.random() * arr.length)
console.log(random) // 0 ~ 3 之间的随机整数
console.log(arr[random]) // 随机名字
// 1.2 把名字放入对应的盒子里面 span
const one = document.querySelector('.one')
one.innerText = arr[random]
// 1.3 不允许重复抽奖,所以要把刚才选出来的名字从数组中删除
// arr.splice(随机数, 1) // 可以删除刚才抽取的名字
arr.splice(random, 1)
console.log(arr)
// 2. 二等奖的做法
// 2.1 利用随机数选取数组中的名字
const random2 = Math.floor(Math.random() * arr.length)
console.log(arr[random2]) // 数组里面的名字
// 2.2 把名字放入对应的盒子里面 span
const two = document.querySelector('.two')
two.innerText = arr[random2]
// 2.3 不允许重复抽奖,所以要把刚才选出来的名字从数组中删除
arr.splice(random2, 1)
console.log(arr)
// 3. 三等奖的做法
// 3.1 利用随机数选取数组中的名字
const random3 = Math.floor(Math.random() * arr.length)
console.log(arr[random3]) // 数组里面的名字
// 3.2 把名字放入对应的盒子里面 span
const three = document.querySelector('.three')
three.innerText = arr[random3]
// 3.3 不允许重复抽奖,所以要把刚才选出来的名字从数组中删除
arr.splice(random3, 1)
console.log(arr)
</script>
</body>
</html>易错点:随机下标要用 Math.floor(Math.random()*arr.length);每次抽完必须从数组中删除,否则可能重复;写入用 innerText 即可。
操作元素常用属性
为什么需要:DOM 不仅能改内容,也能改标签自带属性,比如图片 src、链接 href、title、alt。怎么想:先获取元素,再“对象.属性”读写;有该属性赋新值就是改,没有就是增,赋空字符串可删值。怎么做:
html
<script>
// 1. 先获取这个元素
const img = document.querySelector('img')
// 2. 操作DOM元素常见属性
// 2.1 查
console.log(img.src)
// 2.2 改
img.src = './images/3.png'
// 2.3 增
img.title = '我是播仔,我是不是很可爱'
// 2.4 删
img.alt = ''
</script>随机背景案例:
html
<!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>
img {
width: 600px;
}
</style>
</head>
<body>
<img src="./images/1.png" alt="">
<script>
// 随机显示图片案例
// 图片地址
const arr = [
'./images/1.png',
'./images/2.png',
'./images/3.png',
'./images/4.png'
]
// 获取图片元素
const img = document.querySelector('img')
// 1. 利用随机数抽取数组中的一个地址
const random = Math.floor(Math.random() * arr.length)
console.log(arr[random]) // 得到图片地址
// 2. 把地址赋值给图片src属性
img.src = arr[random]
</script>
</body>
</html>易错点:属性名直接写,不要加多余前缀;改 src 时路径要写对;转写稿中演示了鼠标放图上能看到 title,删 alt 可赋空字符串。
通过 style 操作样式
为什么需要:很多效果要动态改样式,如小圆点换色、图片滚动位置变化。怎么想:样式也在对象里,通过 对象.style.样式属性 修改。怎么做:

html
<script>
// 通过style操作元素样式
// 1. 先要获取这个box元素对象
const box = document.querySelector('.box')
// 2. 通过style来从操作样式
box.style.width = '300px'
box.style.marginTop = '50px'
box.style.backgroundColor = 'skyblue'
// 3. 注意事项
// 3.1 给样式赋值的时候,千万不要忘了加单位比如 300px
// 3.2 如果有-的样式,我们采取的是小驼峰命名法比如 marginTop
// 3.3 一定不要忘了加 style 属性
</script>易错点:赋值要加 CSS 单位;有短横线的样式转小驼峰,如 margin-top 写成 marginTop;别忘写 style。转写稿调试时演示:300 不加 px 不生效且无提示;写成 margin-top 会报错,改 marginTop 才生效;backgroundColor 的 C 要大写。
className 与 classList 操作类样式
为什么需要:样式多时逐条写 style 很繁琐,可把多个样式放进一个类,再把类加到元素上。怎么想:className 是整体换类名,会覆盖旧类名;classList 可追加、删除、切换,更推荐。怎么做:
html
<script>
// 通过类名操作元素样式
// 1. 获取box盒子
const box = document.querySelector('.box')
// 2. 利用类名操作元素样式
// box.className = 'circle'
box.className = 'box circle'
// 3. 利用类名操作样式添加的新的类名会覆盖掉原先的类名
</script>
html
<script>
// 1. 获取box盒子
const box = document.querySelector('.box')
// 2.通过classList操作元素样式(推荐)
// 2.1 追加类名
// box.classList.add('circle')
// 2.2 删除类名
// box.classList.remove('box')
// 2.3 切换类名: 如果元素身上有这个类名,那么就删除,如果没有这个类名则添加
box.classList.toggle('circle')
</script>易错点:class 是关键字,用 className;className 是新值换旧值,需保留旧类名时写成 'box circle';转写稿中直接写 circle 会丢掉 box,导致原宽高等样式失效。
操作表单元素属性
为什么需要:表单常要改 type、value,或控制禁用、勾选。怎么想:普通属性用“DOM对象.属性=新值”;disabled、checked、selected 这类布尔属性用 true/false。怎么做:
html
<script>
// 操作表单属性
// 1. 操作表单 type 和 value 属性
// 1.1 修改type属性
const username = document.querySelector('[name=username]')
console.log(username)
// username.type = 'password'
// 1.2 操作表单的 value 属性
// console.log(username.value) // 查
// username.value = '用户名试试' // 增
// username.value = '请输入用户名' // 改
// username.value = '' // 删
// 2. 禁用按钮或者是勾选复选框 布尔型
// 2.1 禁用按钮
const button = document.querySelector('button')
// button.disabled = true // true 是禁用
button.disabled = false // false 是不禁用
// 2.2 勾选复选框
const agree = document.querySelector('[name=agree]')
console.log(agree)
// agree.checked = true // true 是选中复选框
agree.checked = false // flase 是不选中复选框
</script>易错点:布尔属性不要写字符串 'true';disabled=true 是禁用,false 是不禁用;checked=true 是选中。
自定义属性:data- 与 dataset
为什么需要:有时要在标签上存业务数据,标准属性不够用。怎么想:HTML5 用 data- 开头定义自定义属性,DOM 对象上用 dataset 获取。怎么做:
html
<script>
// 自定义属性
// 1. 获取盒子
const box = document.querySelector('.box')
// 2. 得到自定义属性值
// console.log(box.dataset) // 得到一个对象集合
// console.log(box.dataset.id) // 1
// console.log(box.dataset) // 得到一个对象集合
console.log(box.dataset.name) // box
</script>易错点:标签上写 data- 开头,DOM 上通过 dataset 取;不要和 class、id、title 等标准属性混用;dataset 拿到的是集合对象,再点具体属性名取值。
材料说明与本节范围
本节笔记主题是“定时器-间隔函数”,核心是 setInterval 的开启与关闭。笔记中没有图片,因此无图片可保留;下面保留笔记中的两段代码,并围绕它们扩写。需要说明:提供的转写稿讲的是操作元素常见属性、随机图片、style、类名等内容,与本节“定时器-间隔函数”不匹配,不能把其中的推导和调试过程硬套到定时器上,否则会编造。因此以下只依据本节笔记扩写,不引入转写稿中无关知识点。
为什么需要间隔定时器
为什么需要: 网页中有些功能不能只靠用户点击触发,而是需要“每隔一段时间自动执行一段代码”。笔记给出的典型场景是网页中的倒计时。倒计时需要持续、重复地更新,不可能让用户每秒手动点一次。
怎么想: 先明确“自动”和“重复”两个关键词。自动,意味着不靠手动触发;重复,意味着不是执行一次就结束,而是按固定间隔反复执行。于是需要一种机制:把要重复执行的代码交给定时器,并告诉它间隔多久执行一次。
怎么做: JavaScript 内置了定时器函数,笔记说明定时器函数有两种:间隔函数和延迟函数。本节只讲间隔函数 setInterval。它的作用是间隔固定的时间自动重复执行另一个函数,也叫定时器函数。
易错点: 不要把“间隔函数”和“延迟函数”混为一谈;本节笔记只展开 setInterval,延迟函数不在本节范围内,不能凭感觉补细节。
开启定时器:setInterval 的基本写法
为什么需要: 要实现“每隔一段时间自动执行”,就要先学会开启定时器。开启后才能让一段函数按固定间隔重复运行。
怎么想: setInterval 需要两个关键信息:一是“要重复执行什么”,也就是一个函数;二是“隔多久执行一次”,也就是间隔时间。把这两件事按语法位置写进去即可。
怎么做: 笔记给出的语法如下,代码原样保留:
html
<script>
setInterval(function () {
console.log('我是1秒钟执行一次')
}, 1000)
</script>这段代码中,第一个参数是一个匿名函数,里面写要重复执行的代码;第二个参数是 1000。笔记强调:setInterval 的作用是每隔一段时间调用这个函数;间隔时间单位是毫秒。
易错点: 最容易错的是单位。1000 毫秒才是 1 秒,不要写成 1 就以为是一秒。另一个易错点是函数的位置:这里传入的是函数本身,定时器到时间后才会调用它;不能把“要执行的代码”随便写在 setInterval 外面,否则就失去定时重复执行的意义。
关闭定时器:保存返回值再 clearInterval
为什么需要: 定时器一旦开启会反复执行,如果某些条件下需要停止,就必须能关闭它。笔记明确指出:需要定时器变量名来关闭。
怎么想: 关闭的前提是“能找到这个定时器”。setInterval 执行后会返回一个唯一的数字,笔记用 timer、timer1 保存返回值,并打印出 1、2。因此思路是:开启时把返回值存到变量里,关闭时把这个变量交给 clearInterval。
怎么做: 笔记代码如下,代码原样保留:
html
<script>
let timer = setInterval(repeat, 1000) // 注意调用的时候直接写函数名字不需要写小括号
console.log(timer) // 1
let timer1 = setInterval(repeat, 1000) // 注意调用的时候直接写函数名字不需要写小括号
console.log(timer1) // 2
// 2. 关闭定时器
clearInterval(timer)
</script>从这段代码可以看到:setInterval(repeat, 1000) 中直接写函数名 repeat,不写小括号;返回值分别保存到 timer 和 timer1;最后用 clearInterval(timer) 关闭 timer 对应的定时器。
易错点: 第一,关闭定时器要传“保存返回值的变量”,不是传函数名。第二,笔记强调调用时直接写函数名字不需要写小括号;如果写成 repeat(),含义会变成先执行函数并把结果交给定时器,而不是把函数交给定时器之后按间隔调用。第三,代码中的 repeat 必须是已经定义好的函数,否则运行会报错;笔记重点在语法结构,没有展开 repeat 的函数体。第四,返回的数字虽然示例是 1、2,但笔记只说明它是唯一数字,实际使用时应保存变量,不要依赖具体数字。
调试观察与使用建议
为什么需要: 定时器是“异步重复执行”,只看代码不容易确认是否按预期运行,需要观察输出和关闭效果。
怎么想: 可以先在回调里写 console.log,观察是否按间隔重复打印;再把 setInterval 的返回值打印出来,确认拿到唯一数字;最后调用 clearInterval,观察是否停止。
怎么做: 按笔记示例,在控制台查看 timer 和 timer1 的输出;关闭时执行 clearInterval(timer)。若开启多个定时器,要分别用不同变量保存,关闭哪个就传哪个变量。
易错点: 不要开启多个定时器却只保存一个变量,否则容易关错或无法关闭其他定时器;关闭后原变量仍存在,但对应定时器已停止,不要误以为变量消失;间隔时间单位始终是毫秒。
课件图示








代码示例
示例一:操作元素内容(innerText / innerHTML)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>操作元素内容</title>
<style>
.box,
.box1 {
width: 240px;
height: 60px;
line-height: 60px;
text-align: center;
background-color: pink;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="box">古丽扎娜</div>
<div class="box1">???</div>
<script>
// 操作DOM元素内容
// 1. 对象.innerText 增删改查
// 1.1 查
const box = document.querySelector('.box')
console.log(box.innerText) // 古丽扎娜
// 1.2 改
box.innerText = '迪丽热巴'
// 1.3 增
const box1 = document.querySelector('.box1')
console.log(box1)
box1.innerText = '佟丽丫丫'
// 1.4 删 给空字符串可以删除内容
// box.innerText = ''
// box1.innerText = ''
// 2. 对象.innerHTML 会解析标签
box.innerHTML = '<strong>迪丽热巴</strong>'
</script>
</body>
</html>关键行与易错点
box.innerText:读取标签内部的文本内容,是「查」;box.innerText = '迪丽热巴'是「改」(原来没有的属性名赋值就是「增」)。box.innerText = '':给空字符串就是「删」,页面上文字会消失,但标签还在。innerText不会解析字符串里的标签,写成'<strong>迪丽热巴</strong>'会原样把尖括号显示出来;innerHTML会解析标签,<strong>会变成真正的加粗元素。- 总结:文本里包含 html 标签时用
innerHTML,否则建议用innerText。
示例二:随机显示图片案例(操作元素常用属性 src)
html
<!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>
img {
width: 600px;
}
</style>
</head>
<body>
<img src="./images/1.png" alt="">
<script>
// 随机显示图片案例
// 图片地址
const arr = [
'./images/1.png',
'./images/2.png',
'./images/3.png',
'./images/4.png'
]
// 获取图片元素
const img = document.querySelector('img')
// 1. 利用随机数抽取数组中的一个地址
const random = Math.floor(Math.random() * arr.length)
console.log(arr[random]) // 得到图片地址
// 2. 把地址赋值给图片src属性
img.src = arr[random]
// ---- 操作常见属性的增删改查(与上面同一个 img 对象)----
// 查
console.log(img.src)
// 改
// img.src = './images/3.png'
// 增(原来没有 title 属性,赋值即新增)
// img.title = '我是播仔,我是不是很可爱'
// 删(给空字符串即可)
// img.alt = ''
</script>
</body>
</html>关键行与易错点
- 必须先
document.querySelector('img')拿到 DOM 对象,之后才能img.src = ...;属性名直接点出来,不需要setAttribute。 - 随机下标必须是
Math.floor(Math.random() * arr.length),Math.random()只产生0 ~ 1的小数,不取整会取不到数组元素。 - 路径要写成和页面一致的相对路径(如
./images/1.png),文件不存在时图片就是裂图,容易误以为代码写错。 - 「增 / 改 / 删」都靠赋值完成:原来有这个属性 → 改;原来没有 → 增;赋空字符串 → 相当于删除该属性值。
示例三:通过 style / className / classList 操作元素样式
html
<!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 {
width: 200px;
height: 200px;
background-color: pink;
}
.circle {
border-radius: 50%;
background-color: skyblue;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<div class="box">播仔</div>
<script>
// 1. 先获取这个box元素对象
const box = document.querySelector('.box')
// 2. 通过style来操作样式
box.style.width = '300px'
box.style.marginTop = '50px'
box.style.backgroundColor = 'skyblue'
// 3. 通过 className 操作样式(新值换旧值)
// box.className = 'circle' // 原来的 box 类名被覆盖掉了
// box.className = 'box circle' // 想保留旧类名,用空格隔开
// 4. 通过 classList 操作样式(推荐)
// box.classList.add('circle') // 追加类名
// box.classList.remove('box') // 删除类名
// box.classList.toggle('circle') // 有则删、无则加
</script>
</body>
</html>关键行与易错点
- 修改样式必须走
box.style.xxx,只写box.width是没效果的(所有样式都在 style 里面)。 - 赋值要带单位:
'300px'不能写成300,少了px既不报错也不生效,最难排查。 - 带
-的样式要转小驼峰:margin-top→marginTop、background-color→backgroundColor。 className = 'circle'是替换,原来的box类名会丢失,宽高样式就失效了;要保留旧类名得写成'box circle'。- 更推荐
classList:add/remove/toggle只在原有类名基础上增删,不会覆盖旧类名。
常见错误
1. 改样式时数字不带单位
- 现象:
box.style.width = 300执行后页面毫无变化,控制台也不报错。 - 原因:
style上的属性值最终是 CSS 字符串,纯数字对width、margin-top等长度类属性不合法,浏览器会静默丢弃。 - 修法:写成
'300px';只有无单位属性(opacity、zIndex、lineHeight的无单位值)才可以直接写数字。
2. 漏写 .style,或把连字符属性名原样搬过来
- 现象:
box.width = '300px'没反应;box.style.background-color = 'red'直接语法报错。 - 原因:
width不是元素自带属性,只是给对象加了一个没人读取的自有属性;而background-color里的-被解析成减号运算。 - 修法:一律
对象.style.属性名,多单词改成小驼峰backgroundColor、marginTop。
3. className 赋值把原有类名顶掉
- 现象:给盒子加了个
circle类之后,原来的宽高、背景全失效,页面布局塌了。 - 原因:
className是"整串替换"而不是追加,'circle'覆盖了原来的'box'。 - 修法:要么手动拼回
box.className = 'box circle',要么直接用classList.add('circle')/classList.toggle('circle')做增删,不必关心原有类名。
4. 用 innerText 塞标签字符串,或用 innerHTML 塞用户输入
- 现象:页面上明晃晃显示
<strong>迪丽热巴</strong>这串字;或者输入框内容被当作 HTML 渲染出来。 - 原因:
innerText只认纯文本、不解析标签;innerHTML会解析并执行标签,外部输入直接进 DOM 就是 XSS 入口。 - 修法:需要渲染结构才用
innerHTML;纯文本(尤其是用户数据)用innerText/textContent,或用document.createElement拼节点。
5. 表单布尔属性用字符串赋值
- 现象:
btn.disabled = 'false'、checkbox.checked = 'false',控件依然处于禁用 / 勾选状态。 - 原因:
disabled、checked、selected这类布尔属性只看"属性存不存在",任何非空字符串都算存在,'false'也是真。 - 修法:只赋
true/false布尔值,不要加引号。
6. 自定义属性读错位置
- 现象:
<div data-user-id="7">,box.userId、box.data-userId全是undefined。 - 原因:
data-*不挂在元素自身的普通属性上,而是集中在dataset集合里,且连字符段要转小驼峰。 - 修法:
box.dataset.userId;调试时先console.log(box.dataset)看全集。
7. 定时器写成函数调用,或句柄丢失导致关不掉
- 现象:
setInterval(repeat(), 1000)只跑一次(甚至立刻执行完就没动静);按钮连点几次后数字越跳越快,clearInterval停不下来。 - 原因:传的是函数执行结果而不是函数本身;
timer声明在函数内部每次都是新变量,且重复点击时旧的定时器从未被清除。 - 修法:传函数引用
setInterval(repeat, 1000)或箭头函数;timer用外层let保存,并在开启前先clearInterval(timer)兜底。
练习
练习 1|文案与结构切换 页面上有 <div class="msg"></div>,用一个按钮在两种状态间切换:点击后显示"温馨提示:请先登录"(em 要斜体生效),再点一次恢复成纯文本"温馨提示:请先登录"(<em> 原样显示为字符)。 要求:只用一次 if/else,不新增元素。
练习 2|样式三连改 有一个 200×200 的 .box。用 style 一次性把它改成宽 300px、上外边距 50px、背景 skyblue;随后再写一段代码,用类名方式把它变成圆形并水平垂直居中(已备好 .circle 类)。 要求:两种写法都写出来,并说明第二次改写时为什么不能只写 box.className = 'circle'。
练习 3|登录框的"显示密码" 一个密码输入框和"眼睛"按钮。点击按钮在 password / text 之间切换输入框类型,同时按钮文字在"显示密码"/"隐藏密码"间切换。 要求:用同一个按钮完成切换,不写两个按钮。
练习 4|抽奖升级版 4 人名单,抽出三等奖、二等奖、一等奖各 1 人,不能重复。 要求:把笔记里三段复制粘贴的代码改成一次循环(或一个函数调用三次),并说明为什么必须"先取值、后 splice"。
练习 5|倒计时与清理 页面显示 10 秒倒计时,到 0 停止并显示"时间到"。 要求:写出开启与关闭的完整代码;再补一句说明:如果不保存 setInterval 的返回值会发生什么。
参考要点:
- 分支内分别用
msg.innerHTML = '...<em>...</em>'与msg.innerText = '...<em>...</em>'。box.style.width='300px'; box.style.marginTop='50px'; box.style.backgroundColor='skyblue';第二段用classList.add('circle');因为className是替换,直接赋'circle'会丢掉box类里原有的尺寸样式。- 用一个
let flag = false(或直接判断input.type),在'password'与'text'之间切换,并同步btn.innerText。- 循环内
const i = Math.floor(Math.random()*arr.length); span.innerText = arr[i]; arr.splice(i,1);——若先splice再取值,索引会错位甚至拿到undefined。let timer = setInterval(fn, 1000),fn内递减,到 0 时clearInterval(timer);不保存返回值就没有句柄可传,定时器无法停止。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 操作元素常见属性 | 05:54 |
| 2 | 随机显示图片案例 | 03:54 |
| 3 | 通过style来修改元素样式 | 09:29 |
| 4 | 随机显示背景图片案例 | 05:54 |
| 5 | 通过类名修改元素样式 | 06:56 |
小结
- 改内容先问"要不要渲染结构":要结构用
innerHTML,纯文本一律innerText/textContent;用户输入永远走纯文本这条路。 - 属性操作是统一的"对象.属性 = 值"模型:查用读、改和增都是赋值、删给空字符串;能不能生效取决于这个属性是不是标签自带的。
- 改样式有三档,优先级从低到高:
style适合改一两处、需要动态计算值(如随机坐标)的场合;className只作为"能看懂老代码"的知识点;日常首选classList.add/remove/toggle。 style的三个死穴记牢:必须带.style、连字符转小驼峰、长度值带单位——三者任一漏掉都是"不报错但不生效",排查成本最高。- 布尔属性(
disabled/checked/selected)只认真布尔值,字符串'false'会被当成"有属性"。 - 自定义数据统一走
data-*+dataset(连字符转小驼峰),这是把数据挂在 DOM 上再取回的标准姿势。 setInterval的返回值必须用外层变量接住,否则关不掉;重复触发的场景(点击、切换)要先clearInterval再开新的,避免叠加。- 案例题的通用骨架就三步:取元素 → 随机/计算得到数据 → 把数据写回元素属性;随机不重复的关键是取完立刻从数组里删掉,索引和数组始终同步。