DOM作用
开发网页特效、实现用户交互
DOM树
体现了标签和标签的关系
DOM对象 (重要)
<div>123</div>
<script>
const div = document.querySelector('div')
console.dir(div);
</script>
DOM核心思想,把网页内容当作对象
document是一个对象,整个页面中最大的一个对象
获取DOM元素
CSS选择器获取
只匹配的第一个元素
<div class="box">123</div>
<div class="box">abc</div>
<script>
const box = document.querySelector('div')
console.log(box)
</script>
获取所有的
<div class="box">123</div>
<div class="box">abc</div>
<script>
const box = document.querySelectorAll('div')
console.log(box)
</script>
SelectorAll获得的是伪数组
<ul>
<li>我的首页</li>
<li>产品介绍</li>
<li>联系方式</li>
</ul>
<script>
const lis = document.querySelectorAll('ul li')
for (let i = 0; i < lis.length; i++) {
console.log(lis[i]);
}
</script>
操作元素内容
.innerText
只改内容,不解析标签
<div class="box">文字内容</div>
<script>
const box = document.querySelector('.box')
box.innerText = '盒子'
</script>
.innerHTML
也可以解析标签
<div class="box">文字内容</div>
<script>
const box = document.querySelector('.box')
box.innerHTML = '<strong>更换</strong>'
</script>
随机数抽奖案例
<div>
<li one></li>
<li two></li>
<li three></li>
</div>
<script>
const personArr = ['小明', '小红', '小蓝', '小绿', '小粉']
const radom = Math.floor(Math.random() * personArr.length)
const lis = document.querySelectorAll('div li')
for (let i = 0; i < lis.length; i++) {
const radom = Math.floor(Math.random() * personArr.length)
lis[i].innerHTML = personArr[radom]
personArr.splice(radom, 1)
}
</script>
修改元素属性
常用属性
<img src="tk.jpg" alt="">
<script>
const pic = document.querySelector('img')
pic.src = 'h.jpg'
</script>
刷新随机修改图片案例:
<img src="pic1.jpg" alt="">
<script>
function getRandom(N, M) {
return Math.floor(Math.random() * (M - N + 1)) + N
}
const img = document.querySelector('img')
const random = getRandom(1, 7)
img.src = `pic${random}.jpg`
</script>
修改样式
通过style
<div class="box"></div>
<script>
const box = document.querySelector('.box')
box.style.width = '300px'
box.style.backgroundColor = 'yellow'
box.style.border = '2px solid red'
box.style.borderBottom = '2px solid pink'
</script>
记得加单位、小驼峰命名
通过类名(修改的样式很多的时候)
const div = document.querySelector('div')
div.className = 'box'
div {
width: 200px;
height: 200px;
background-color: pink;
}
.box {
background-color: aqua;
}
注意会直接覆盖以前的类名,可以两个类名都写上
classList(常用,重点!)
追加类
const div = document.querySelector('div')
div.classList.add('active')
删除类
div.classList.remove('box')
切换类
toggle,有就删掉,没有就加上
修改表单属性
获取表单里的内容只能用value,innerHTML不可以
<input type="text" value="电脑">
<script>
const uname = document.querySelector('input')
console.log(uname.value);
</script>
const uname = document.querySelector('input')
uname.value = '我要买电脑'
复选框,是否勾选,checked改为ture或者false
<input type="checkbox" name="" id="">
<script>
const ipt = document.querySelector('input')
ipt.checked = true
</script>
button,禁用,disabled
const button = document.querySelector('button')
button.disabled = false
自定义属性
xxx.dataset.xxx
<div data-id="1" data-s="不知道">1</div>
<div data-id="2">2</div>
<div data-id="3">3</div>
<div data-id="4">4</div>
<div data-id="5">5</div>
<script>
const one = document.querySelector('div')
console.log(one.dataset.id);
console.log(one.dataset.s);
</script>
定时器-间歇函数
用于网页中的倒计时
开启定时器:
setInterval(function () {
console.log('一秒执行一次');
}, 1000)
function fn() {
console.log('一秒执行一次');
}
setInterval(fn, 1000)
函数名不需要加括号,每个定时器都有一个编号
关闭定时器:
function fn() {
console.log('一秒执行一次');
}
let n = setInterval(fn, 1000)
clearInterval(n)
阅读用户协议案例
<button>已阅读用户协议(5)</button>
<script>
const button = document.querySelector('button')
button.disabled = true
let i = 5
let num = setInterval(function () {
i--
button.innerHTML = `已阅读用户协议(${i})`
if (i == 0) {
clearInterval(num)
button.disabled = false
button.innerHTML = '同意协议'
}
}, 1000)
</script>
自动轮播图案例
const img = document.querySelector('.slider-wrapper img')
const p = document.querySelector('.slider-footer p')
let i = -1
setInterval(function () {
i++
img.src = sliderData[i].url
p.innerHTML = sliderData[i].title
document.querySelector('.slider-indicator .active').classList.remove('active')
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
if (i == 7) {
i = -1
}
}, 1000)
classList.remove 移除上一个不用的小圆点 有事件发生,用一个函数响应
语法:元素对象.addEventListenter('事件类型',要执行的函数)
三要素:DOM元素(事件源),事件类型,调用函数
<button>点击</button>
<script>
const button = document.querySelector('button')
button.addEventListener('click', function () {
alert('你好')
})
</script>
随机点名案例机点名案例点名案例
<script>
// 数据数组
const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
const qs = document.querySelector('.qs')
// 开始
let num = 0
let random = 0
const start = document.querySelector('.start')
start.addEventListener('click', function () {
num = setInterval(function () {
random = parseInt(Math.random() * arr.length)
qs.innerHTML = arr[random]
}, 35)
if (arr.length === 1) {
start.disable = true
end.disable = true
}
})
//关闭
const end = document.querySelector('.end')
end.addEventListener('click', function () {
clearInterval(num)
arr.splice(random, 1)
console.log(arr);
})
</script>
鼠标事件
mouseenter
mouseleave
<script>
const div = document.querySelector('div')
div.addEventListener('mouseenter', function () {
console.log('我来了');
})
div.addEventListener('mouseleave', function () {
console.log('我走了');
})
</script>
完整版轮播图
自动播放,鼠标移开停止播放
let num = setInterval(function () {
//自动调用点击!!!!!!
next.click()
}, 1000)
const slider = document.querySelector('.slider')
slider.addEventListener('mouseenter', function () {
clearInterval(num)
})
slider.addEventListener('mouseleave', function () {
clearInterval(num)
//重新开启一个
num = setInterval(function () {
//自动调用点击!!!!!!
next.click()
}, 1000)
console.log(num);
})
num不是同一个,每次开启的都是新的
焦点事件
focus blur
<input type="text">
<script>
const input = document.querySelector('input')
input.addEventListener('focus', function () {
console.log('有焦点触发');
})
input.addEventListener('blur', function () {
console.log('失去焦点触发');
})
</script>
小米搜索框案例
<script>
const input = document.querySelector('input')
const ul = document.querySelector('.result-list')
input.addEventListener('focus', function () {
ul.style.display = 'block'
input.classList.add('search')
})
input.addEventListener('blur', function () {
ul.style.display = 'none'
input.classList.remove('search')
})
</script>
键盘事件
const input = document.querySelector('input')
input.addEventListener('keydown', function () {
console.log('键盘按下了');
})
input.addEventListener('keyup', function () {
console.log('键盘弹起了了');
})
按下和弹起是连续发生的
输入文本事件
input.addEventListener('input', function () {
console.log('文本输入了');
})
评论字数案例
transition: all 0.5s; 淡入淡出
div.innerHTML = ${input.value.length}/200字
<style>
input {
width: 200px;
height: 20px;
}
input:focus {
width: 300px;
}
div {
opacity: 0;
width: 100px;
height: 10px;
transition: all 0.5s;
}
</style>
</head>
<body>
<input type="text" placeholder="发一条友善的评论吧">
<div>0/200字</div>
<script>
const input = document.querySelector('input')
const div = document.querySelector('div')
input.addEventListener('input', function () {
div.innerHTML = `${input.value.length}/200字`
})
input.addEventListener('focus', function () {
div.style.opacity = 1
})
input.addEventListener('blur', function () {
div.style.opacity = 0
})
</script>
</body>
事件对象
存事件触发时的相关信息
可以判断用户按下哪个键,点击了哪个元素
比如按下回车键,就可以发布信息
用event,ev,e表示
常用属性
const input = document.querySelector('input')
input.addEventListener('keyup', function (e) {
console.log(e.key);
})
input.addEventListener('keyup', function (e) {
if (e.key === 'Enter')
console.log('按下了回车键');
})
trim方法
去除字符串左右的空格
const str = ' lyt'
console.log(str.trim())
评论回车发布案例
<script>
const tx = document.querySelector('#tx')
const item = document.querySelector('.item')
const text = document.querySelector('.text')
tx.addEventListener('keyup', function (e) {
if (e.key === 'Enter') {
if (tx.value.trim() !== '') {
item.style.display = 'block'
text.innerHTML = tx.value
tx.value = ''
}
}
})
</script>
环境对象
指函数内部特殊的变量this,它代表当前函数运行时所处的环境
普通和函数里面this指向的是window
谁调用函数,this就指向谁
如果一样的对象有很多个,用this就不会弄混了
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
this.style.color = 'red'
})
回调函数
将函数A作为参数传递给B,函数A就是回调函数
tab切换案例
“先干掉别人,自己登基”
const as = document.querySelectorAll('.tab-nav a')
for (let i = 0; i < as.length; i++) {
as[i].addEventListener('mouseenter', function () {
document.querySelector('.tab-nav .active').classList.remove('active')
this.classList.add('active')
document.querySelector('.tab-content .active').classList.remove('active')
document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
})
}
全选框案例
<script>
const checkAll = document.querySelector('#checkAll')
const cks = document.querySelectorAll('.ck')
checkAll.addEventListener('click', function () {
for (let i = 0; i < cks.length; i++) {
cks[i].checked = checkAll.checked;
}
})
</script>
// 小控制大
for (let i = 0; i < cks.length; i++) {
cks[i].addEventListener('click', function () {
checkAll.checked = document.querySelectorAll('.ck:checked').length === cks.length
})
}
querySelector () 里面的类是css的类,而不是script的DOM元素
事件流 指事件执行过程的流动路径
捕获阶段,冒泡阶段
实际中使用冒泡多
事件捕获
<div class="father">
<div class="son"></div>
</div>
<script>
const fa = document.querySelector('.father')
const so = document.querySelector('.son')
fa.addEventListener('click', function () {
alert('我是爸爸')
}, true)
so.addEventListener('click', function () {
alert('我是儿子')
}, true)
</script>
只点击儿子的盒子,会有两次提醒,先是父亲的提醒,然后再到儿子的提醒(从大的往下流动,直到找到目标)
事件冒泡
把true去掉
点击儿子的盒子,会有两次提醒,先是儿子的提醒,然后再到父亲的提醒(从小的往上流动,调用所有父级)
阻止冒泡(阻止流动传播)
事件对象.stopPropagation()
so.addEventListener('click', function (e) {
alert('我是儿子')
e.stopPropagation()
})
解绑事件
<script>
const button = document.querySelector('button')
function fn() {
alert('点击了')
}
button.addEventListener('click', fn)
button.removeEventListener('click', fn)
</script>
函数fn写在外面,remove之后再点击就不会再有显示了
鼠标经过离开的区别
mouseenter,mouseleave没有冒泡
mouseover,mouseout有冒泡
事件委托
代替for循环
把子元素绑定在父元素身上,点击子元素,会冒泡到父元素,从而触发父元素事件
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<p>6</p>
</ul>
<script>
const ul = document.querySelector('ul')
ul.addEventListener('click', function (e) {
if (e.target.tagName === 'LI') {
e.target.style.color = 'red'
}
})
</script>
tagName是区分ul中所有不同种类元素的方法,小li会变色,p不会变色
tab栏案例
<script>
const ul = document.querySelector('.tab-nav ul')
ul.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
document.querySelector('.tab-nav .active').classList.remove('active')
e.target.classList.add('active')
const i = e.target.dataset.id
document.querySelector('.tab-content .active').classList.remove('active')
document.querySelector(`.tab-content .item:nth-child(${+i + 1})`).classList.add('active')
}
})
</script>
i是一个字符串,前面要+1变成数字
阻止默认行为
e.preventDefault()
<script>
const form = document.querySelector('form')
form.addEventListener('submit', function (e) {
e.preventDefault()
})
</script>
其他事件
页面加载事件
加载外部资源完了,再触发
js写在head中时使用
load事件,监听整个事件,给widow加
DOMContentLoaded
给document加
无需等待样式表、图像完全加载
页面滚动事件
scrollTop 往上滚了多少像素,被卷去的头部
div滚动了多少
<script>
const div = document.querySelector('div')
div.addEventListener('scroll', function () {
console.log(div.scrollTop);
})
</script>
window页面滚动,先隐藏div,页面滚动一定长度再出现
<script>
const div = document.querySelector('div')
window.addEventListener('scroll', function () {
const n = document.documentElement.scrollTop
if (n >= 100) {
div.style.display = 'block'
}
else {
div.style.display = 'none'
}
})
</script>
scroll是可读写的
document.documentElement.scrollTop = 800
这样一打开就是已经滚了800的位置
电梯栏案例
<script>
const ele = document.querySelector('.xtx-elevator')
window.addEventListener('scroll', function () {
const n = document.documentElement.scrollTop
if (n >= 300) {
ele.style.opacity = 1
}
else {
ele.style.opacity = 0
}
})
</script>