highlight: atelier-plateau-light theme: z-blue
1. 全选文本框案例
1.注意这个伪类选择器
可以直接识选中的对象
/* 选择被勾选的复选框 */ .ck:checked { width: 20px; height: 20px;}
- 这种All选择的对象想要设置事件时也要用for循环遍历设置
js
<script>
// 获取大按钮对象
const checkAll = document.querySelector('#checkAll')
// 获取所有小按钮的对象
const cks = document.querySelectorAll('.ck')
// 设置事件:点击大复选框,小的跟着变化
checkAll.addEventListener('click',function(){
// 我们要去便利cks中的每一个对象,让它们的状态和大复选框一致
for(let i= 0 ; i < cks.length; i++){
cks[i].checked = this.checked // chcked是属性,也可以写成checkAll.checked
}
})
// 实现功能:当所有的小按钮被选的时候,大按钮被选中
// 要给所有的小复选框添加点击事件,用循环实现
for(let i = 0; i < cks.length; i++){
cks[i].addEventListener('click',function(){
// for(let i = 0; i < cks.length; i++){
// if(cks[i].checked === false){
// break
// }
// if(i === cks.length - 1){
// checkAll.checked = true
// }
// }
checkAll.checked = document.querySelectorAll('.ck:checked').length === cks.length
})
}
</script>
2.事件流

3.事件捕获

js
<script>
const father = document.querySelector('.father')
const son = document.querySelector('.son')
father.addEventListener('click',function(){
alert('我是爸爸')
},true)
son.addEventListener('click',function(){
alert('我是儿子')
},true)
document.addEventListener('click',function(){
alert('我是爷爷')
},true)
</script>
4.事件冒泡(重要)

5.阻止冒泡(重要)

js
<script>
document.addEventListener('click',function(){
alert('我是爷爷')
})
const father = document.querySelector('.father')
const son = document.querySelector('.son')
father.addEventListener('click',function(){
alert('我是爸爸')
})
son.addEventListener('click',function(e){
alert('我是儿子')
e.stopPropagation()
})
</script>
6.解绑事件
6.1 L0事件移除
如果是用on创建的方法,如
button.onclick = function(){},可以用button.onclick = null解绑

6.2 L2事件移除
L2中匿名函数无法被解绑
js
<script>
const btn = document.querySelector('button')
function fn(){
alert('点击了')
}
btn.addEventListener('click',fn)
// 事件移除解绑
btn.removeEventListener('click',fn)
</script>
6.3 mouseover和mouseenter的区别
- 推荐用mouseenter来阻止冒泡

7.事件委托

js
<body>
<ul>
<li>第1个孩子</li>
<li>第2个孩子</li>
<li>第3个孩子</li>
<li>第4个孩子</li>
<li>第5个孩子</li>
<p>别让我别红</p>
</ul>
<script>
// 点击每个小li,当前li变成红色,点它的其它孩子不变色
const ul = document.querySelector('ul')
// 把事件委托给父级
// 但是要拿到点击的元素
ul.addEventListener('click',function(e){
//e.target就是实际点击的对象·
if(e.target.tagName === 'LI'){
e.target.style.color = 'red'
console.dir(e.target);
}
})
</script>
</body>
8.利用数组委托实现tab栏切换
用到了自定义属性以及两种解决方法
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>tab栏切换</title>
<style>
* {
margin: 0;
padding: 0;
}
.tab {
width: 590px;
height: 340px;
margin: 20px;
border: 1px solid #e4e4e4;
}
.tab-nav {
width: 100%;
height: 60px;
line-height: 60px;
display: flex;
justify-content: space-between;
}
.tab-nav h3 {
font-size: 24px;
font-weight: normal;
margin-left: 20px;
}
.tab-nav ul {
list-style: none;
display: flex;
justify-content: flex-end;
}
.tab-nav ul li {
margin: 0 20px;
font-size: 14px;
}
.tab-nav ul li a {
text-decoration: none;
border-bottom: 2px solid transparent;
color: #333;
}
.tab-nav ul li a.active {
border-color: #e1251b;
color: #e1251b;
}
.tab-content {
padding: 0 16px;
}
.tab-content .item {
display: none;
}
.tab-content .item.active {
display: block;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab-nav">
<h3>每日特价</h3>
<ul>
<li><a class="active" href="javascript:;" data-id = "0" >精选</a></li>
<li><a href="javascript:;" data-id = "1">美食</a></li>
<li><a href="javascript:;" data-id = "2">百货</a></li>
<li><a href="javascript:;" data-id = "3">个护</a></li>
<li><a href="javascript:;" data-id = "4">预告</a></li>
</ul>
</div>
<div class="tab-content">
<div class="item active"><img src="./images/tab00.png" alt="" /></div>
<div class="item"><img src="./images/tab01.png" alt="" /></div>
<div class="item"><img src="./images/tab02.png" alt="" /></div>
<div class="item"><img src="./images/tab03.png" alt="" /></div>
<div class="item"><img src="./images/tab04.png" alt="" /></div>
</div>
</div>
<script>
// 功能:采取事件委托的方式实现tab栏切换
// 将事件委托给a的父类ul
// 获取ul对象
const ul = document.querySelector('.tab-nav ul')
// 获取item对象,就不需要用nth-child了
const items = document.querySelectorAll('.tab-content .item')
// 设置事件
ul.addEventListener('click',function(e){
if(e.target.tagName === 'A'){
document.querySelector('.tab-nav .active').classList.remove('active')
// this指向ul,不能用this
e.target.classList.add('active')
}
//利用自定义属性来获取下面对应的图片 data-id
// 先删除active
document.querySelector('.tab-content .active').classList.remove('active')
// 利用自定义属性来获取顺序
const i = +e.target.dataset.id // 要进行隐式转换
// document.querySelector(`.tab-content .item:nth-child(${num+1})`).classList.add('active')
items[i].classList.add('active')
})
</script>
</body>
</html>
9.阻止默认行为
js
<body>
<form action="http://www.itcast.cn">
<input type="submit" value="点击跳转">
</form>
<a href="http:www.baidu.com">百度一下</a>
<script>
const form = document.querySelector('form')
form.addEventListener('submit',function(e){
// 阻止默认行为,提交
e.preventDefault()
})
// 把链接的默认行为阻止
const a = document.querySelector('a')
addEventListener('click',function(e){
// 阻止默认行为,提交
e.preventDefault()
})
</script>
</body>
10.其它事件
10.1 页面加载事件
1.有些时候,js会写在body上面,正常来说,代码会从上往下执行,那js代码就会执行失败,所以说就需要load事件来保证页面加载完毕之后,再执行对应的函数。

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 页面加载事件,所有资源加载完
window.addEventListener('load',function(){
const btn = document.querySelector('button')
btn.addEventListener('click',function(){
alert('哈哈');
})
})
</script>
</head>
<body>
<button>点我呀</button>
</body>
</html>
1.另一种加载事件比较特殊,它可以实现图片还没有加载完全的时候已经可以实现交互效果了,只需要加载DOM元素就可以了,不需要等待图片的加载,所以比load要快。

10.2 页面滚动事件
1.很多时候用户滚动时要产生一些效果,而且不仅仅是页面可以滚动,很多标签也可以滚动
2.要了解scrollTop和scrollLeft属性,可以手写一个div然后拉动的时候输出scrollTop,这个可读写所以我们也能做到一打开页面滚动条就在中间位置。
3.我们日常很多时候滚动全屏时用的是html标签,获取html标签的方式是document.documentElement,然后可以设置滑动多少距离发生对应的事件

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
overflow: scroll;
margin: 200px;
width: 200px;
height: 200px;
border: 1px solid black;
color:black;
}
</style>
</head>
<body>
<div>
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
</div>
<script>
const div = document.querySelector('div')
div.addEventListener('scroll',function(){
console.log(`scrollTop=${div.scrollTop},scrollLeft=${div.scrollLeft}`)
})
</script>
</body>
</html>
11.页面尺寸事件
1 resize可以实现窗口尺寸变化时触发对应的事件,可以直接用wondow对象调用
2.clientWidth和clientHeight这两个元素可以使用用js获取对象的宽和高(不包含margin、border和滚动条,包括padding)
3.flexible源码就利用了这个事件
12.元素尺寸与位置
12.1 元素尺寸
1.offsetWidth和offsetHeight两个元素可以获取元素的自身宽高(包含padding和border),获取出来的是数值,便于计算
2.获取的是可视宽高,隐藏的盒子返回0

12.2 元素位置(核心)
1.明白
offsetLeft和ofsetTop属性,它们可以获取元素的定位,但是是相对于带有定位的父级的距离,如果都没有就以文档左上角为准。2.好处是:比如滚轮滚到某个元素的时候触发事件,就不需要用具体数值了(因为网页添加新元素具体的数字会改变)
js
<script>
const div = document.querySelector('div')
const p = document.querySelector('p')
// offsetLeft是检测盒子距离最近一级带有定位元素的祖先元素
// 在div中添加一个position: relative 那么p的offsetLeft就会变成50
console.log(div.offsetLeft) // 108
console.log(p.offsetLeft) // 158
</script>