、
this和e.target的区别
给ul加事件委托,li加点击事件
e.target是指触发事件
this指的是绑定事件
事件流
事件流质的是事件完整执行过程中的流动路径 事件出发后的流程
捕获阶段 从父到子
冒泡阶段 从子到父
事件捕获
<!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>Document</title>
</head>
<body>
<!-- DOM.addEventListener(事件类型,事件处理函数,是否进行捕获) -->
<div class="father">
<div class="son"></div>
</div>
<script>
document.addEventListener('click',function(){
alert('我是爷爷')
},true)
fa.addEventListener('click',function(){
alert('我是爸爸')
},true)
son.addEventListener('click',function(){
alert('我是儿子')
},true)
</script>
</body>
</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>Document</title>
</head>
<body>
<style>
.father{
width: 200px;
height: 200px;
border: 1px solid #000;
}
.son{
width: 100px;
height: 100px;
background-color: pink;
}
</style>
<div class="father">
<div class="son"></div>
</div>
<script>
const fa=document.querySelector('.father' )
const son=document.querySelector('.son' )
fa.addEventListener('click',function(){
alert('我是爸爸')
})
son.addEventListener('click',function(e){
alert('我是儿子')
e.stopPropagation() //事件对象.stopPropagation()
})
</script>
</body>
</html>
事件对象的其他方法
<script>
<a href="http://www.jd.com"></a>
//点击 a,打印内容 ,并且不跳转
// 事件对象.preventDefault() 阻止默认行为
</script>
两种事件的注册和解绑
注册 on
on 注册 同类型的时间只能注册一个
on 无法开启捕获 只能是默认的冒泡
事件监听 同类型的时间可以注册多个
可以开启捕获
<script>
btn.onclick=function(){
console.log(1);
}
</script>
事件监听
<script>
btn.addEventListener('click',function(){
console.log('a');
})
</script>
事件解绑 on
<script>
btn.onclick=null
</script>
事件监听解绑
元素.removeEventListener('事件类型',事件处理函数的名称)
必须先给事件处理函数命名
<script>
// 元素.removeEventListener('事件类型',事件处理函数的名称)
// 必须先给事件处理函数命名
const f1=function(){
console.log('a');
}
btn.addEventListener('click',f1)
</script>
mouseenter和mouseover区别
// 在事件对象 e中看bubbles ,true支持冒泡
//mouseenter mouseleave不支持冒泡 推荐使用
//mouseover mouseout支持冒泡
<script>
// 在事件对象 e中看bubbles ,true支持冒泡
//mouseenter mouseleave不支持冒泡 推荐使用
//mouseover mouseout支持冒泡
元素.addEventListener('click', function (e) {
console.log(e);
})
</script>
事件委托
//事件委托 把事件注册给上级元素
//1.给上级元素注册事件
//2.利用事件对象.target找到目标元素
//3.利用e.target.tagName判断标签名是否是我们需要的
<!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>Document</title>
</head>
<body>
<ul>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
</ul>
<script>
//原理 利用事件冒泡
// // 获取元素
// const lis=document.querySelectorAll('li' )
// // 循环遍历
// for(let i=0;i<lis.length;i++){
// // 添加事件监听
// lis[i].addEventListener('click',function(){
// this.style.background='red'
// } )
// }
const ul =document.querySelectorAll('ul' )
ul.addEventListener('click', function (e) {
//tagName 获取标签名:注意是大写的 以前用nodeName
// console.log(e.target.tagName);
if(e.target.tagName ==='LI' ){
e.target.style.background='red'
}
})
</script>
</body>
</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>Document</title>
</head>
<body>
<!-- e.target 获取目标元素 -->
<style>
div{
width: 200px;
border: 1px solid #000;
}
</style>
<!-- 目标元素 记录最先触发事件的元素 -->
<div>
<p>1</p>
<span>1</span>
<p>2</p>
<h1>2</h1>
<p>3</p>
<p>4</p>
<strong>1</strong>
<p>5</p>
<p>6</p>
</div>
<script>
// 事件委托
// 获取元素
const div=document.querySelector('div' )
div.addEventListener('click',function(e){
// 选取目标元素
if(e.target.tagName==='P'){
e.target.style.background='yellow'
}
})
</script>
</body>
</html>
tab栏切换
<!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-index="1">精选</a></li>
<li><a href="javascript:;" data-index="2">美食</a></li>
<li><a href="javascript:;" data-index="3">百货</a></li>
<li><a href="javascript:;" data-index="4">个护</a></li>
<li><a href="javascript:;" data-index="5">预告</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>
// 事件委托
// 获取元素
const ul=document.querySelector('ul')
ul.addEventListener('click',function(e){
//判断
if(e.target.tagName==='A' ){
// 删除active类名
document.querySelector('.tab-nav .active' ).classList.remove('active')
//添加active类名
e.target.classList.add('active')
}
//删除active类名
document.querySelector('.tab-content .active ').classList.remove('active')
//获取item让其显示
document.querySelector(`.item:nth-child(${+e.target.dataset.index} )`).classList.add('active')
})
</script>
</body>
</html>
加载事件
//加载事件:当资源加载完毕执行的事件
//load
<!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>Document</title>
</head>
<body>
<img src="./images/b04.jpg" alt="">
<script>
//加载事件:当资源加载完毕执行的事件
//load
document.querySelector('img')
img.addEventListener('load',function(){
console.log('加载完毕');
})
//等所有资源加载完毕,load事件添加给window
window.addEventListener('load',function(){
console.log('window');
})
//给document加 加载快
document.addEventListener('DOMContentLoaded',function(){
console.log('document');
})
</script>
</body>
</html>
页面滚动事件
//scroll :滚动事件,滚动条滚动的时候触发
//scroll:谁有滚动条加给谁
<!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>Document</title>
</head>
<body>
<style>
div{
width: 200px;
height: 200px;
border: 1px solid #000;
overflow: auto;
}
</style>
<input type="button" value="">
<div>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
<p>10</p>
<p>11</p>
<p>12</p>
<p>13</p>
<p>14</p>
<p>15</p>
<p>16</p>
<p>17</p>
<p>18</p>
<p>19</p>
<p>20</p>
<p>21</p>
<p>22</p>
<p>23</p>
<p>24</p>
<p>25</p>
<p>26</p>
<p>27</p>
<p>28</p>
<p>29</p>
<p>30</p>
</div>
<script>
//scroll :滚动事件,滚动条滚动的时候触发
//scroll:谁有滚动条加给谁
const div=document.querySelector('div')
div.addEventListener('scroll',function(){
console.log('加载完毕');
// 数字类型值,像素 滚上去的距离
console.log(div.scrollTop);
const btn=document.querySelector('input')
btn.addEventListener('click',function(){
//scrollTop 可以获取也可以设置
div.scrollTop=0
})
})
</script>
</body>
</html>
scroll事件
//scroll
//如果整个窗口具有滚动条,那么滚动事件加给window
<!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>Document</title>
</head>
<body>
<style>
body{
height: 3000px;
background: linear-gradient(red,blue );
}
</style>
<script>
//scroll
//如果整个窗口具有滚动条,那么滚动事件加给window
window.addEventListener('scroll',function(){
console.log(document.documentElement.scrollTop);//scrollTop找的是html的值 若文档头删除 找的是body的值
})
</script>
</body>
</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>Document</title>
</head>
<body>
<style>
.father{
position: relative;
width: 200px;
height: 200px;
background-color: red;
}
style>
.son{
position: absolute;
left: 20px;
top: 20px;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<div class="father">
<div class="son">
</div>
</div>
<script>
const son=document.querySelector('.son')
console.log(son.offsetLeft,son.offsetTop);
//当上级没有定位,根据文档定位
//相对于定位元素的位置,参照带定位的父级元素
</script>
</body>
</html>
电梯导航
<style>
html{
scroll-behavior: smooth;
}
</style>
<script>
window.addEventListener('scroll',function(){
const elevator=document.querySelector('.xtx-elevator')
//页面卷出去300让电梯兰显示,否则不显示
if( document.documentElement.scrollTop >=300){
elevator.style.opacity=1
}else{
elevator.style.opacity=0
}
})
const backTop=document.querySelector('#backTop')
backTop.addEventListener('click',function(){
//返回顶部
document.documentElement.scrollTop=0
})
// window.scrollTo(0,0)
</script>
获取大小
// clientWidth , clientHeight //获取页面大小
// client:包含width+padding
//offsetWidth.offsetHeight //获取元素大小
//offset:包含:width+padding+border
<div></div>
<script>
const div=document.querySelector('div')
//console.log(div.style.width )//设置
// clientWidth , clientHeight
// client:包含width+padding
console.log(div.clientWidth,div.clientHeight);//获取页面大小
//offsetWidth.offsetHeight
//offset:包含:width+padding+border
console.log(div.offsetWidth,div.offsetHeight);//获取元素大小
// 只用于获取元素
//修改元素
div.clientWidth=1000
div.style.width='1000px'
</script>
resize事件
<script>
window.addEventListener('resize',function(){
console.log('尺寸变小了');
//获取页面
html=document.documentElement.clientWidth;
document.documentElement.style.fontSize=html /80 +'px'
})
</script>
全选反选案例
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
width: 500px;
margin: 100px auto;
text-align: center;
}
th {
background-color: #09c;
font: bold 16px "微软雅黑";
color: #fff;
height: 24px;
}
td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
.allCheck {
width: 80px;
}
</style>
</head>
<body>
<table>
<tr>
<th class="allCheck">
<input type="checkbox" name="" id="checkAll"> <span class="all">全选</span>
</th>
<th>商品</th>
<th>商家</th>
<th>价格</th>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米手机</td>
<td>小米</td>
<td>¥1999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米净水器</td>
<td>小米</td>
<td>¥4999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米电视</td>
<td>小米</td>
<td>¥5999</td>
</tr>
</table>
<script>
// 获取大复选框
const checkAll=document.querySelector('#checkAll')
// 获取小复选框
const cks=document.querySelectorAll('.ck')//cks=[ck,ck,ck]
// 给大复选框添加事件监听
checkAll. addEventListener('click',function(){
// console.log(checkAll.checked);
let flag=checkAll.checked
//遍历小复选框,让小复选框的checked=大复选框的checked
for(let i=0;i<cks.length;i++ ){
cks[i].checked=flag
}
});
//点击小的效果
for (let i = 0; i < cks.length; i++){
// 给小复选框添加事件监听
cks[i].addEventListener('click', function () {
const len1 = cks.length
const len2=document.querySelectorAll('.ck:checked').length;
checkAll.checked = len1 === len2
// if(len1 === len2 ){
// checkAll.checked=true;
// }else{
// checkAll.checked=false
// }
})
}
/* // 点击小的效果
for (let i = 0; i < cks.length; i++) {
// 监听事件
cks[i].addEventListener('click', function () {
// 判断全选是否都选中
// 查看小的是否都选中,如果都选中大的就选中,否则不选中
// 如果小按钮个数等于被选中小按钮的个数,说明都选中
// 小按钮的个数
const len1 = cks.length
// 选中的小按钮的个数
const len2 = document.querySelectorAll('.ck:checked').length
// 判断
checkAll.checked = len1 === len2
})
} */
</script>
</body>
</html>
元素的位置
元素.offsetLeft
元素.offsetTop
<!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>Document</title>
</head>
<body>
<style>
.father{
position: relative;
width: 200px;
height: 200px;
background-color: red;
}
.son{
position: absolute;
left: 20px;
top: 20px;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<div class="father">
<div class="son">
</div>
</div>
<script>
const son=document.querySelector('.son')
console.log(son.offsetLeft,son.offsetTop);
//当上级没有定位,根据文档定位
//相对于定位元素的位置,参照带定位的父级元素
</script>
</body>
</html>
仿新浪固定头部
当页面滚动到秒杀模块时,顶部导航栏会显示出来 卷出去的高度大于元素的offsetTop
<!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>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.content {
overflow: hidden;
width: 1000px;
height: 3000px;
background-color: pink;
margin: 0 auto;
}
.backtop {
display: none;
width: 50px;
left: 50%;
margin: 0 0 0 505px;
position: fixed;
bottom: 60px;
z-index: 100;
}
.backtop a {
height: 50px;
width: 50px;
background: url(./images/bg2.png) 0 -600px no-repeat;
opacity: 0.35;
overflow: hidden;
display: block;
text-indent: -999em;
cursor: pointer;
}
.header {
position: fixed;
top: -80px;
left: 0;
width: 100%;
height: 80px;
background-color: purple;
text-align: center;
color: #fff;
line-height: 80px;
font-size: 30px;
transition: all .3s;
}
.sk {
width: 300px;
height: 300px;
background-color: skyblue;
margin-top: 500px;
}
</style>
</head>
<body>
<div class="header">我是顶部导航栏</div>
<div class="content">
<div class="sk">秒杀模块</div>
</div>
<div class="backtop">
<img src="./images/close2.png" alt="">
<a href="javascript:;"></a>
</div>
<script>
const sk=document.querySelector('.sk')
const header=document.querySelector('.header')
//页面滚动到秒杀模块,显示顶部导航栏
window.addEventListener('scroll',function(){
//卷出去的距离大于秒杀模块到顶部距离,显示导航栏
// document.documentElement.scrollTop //卷出去的距离
// ck.offsetTop //模块到顶部距离
if(document.documentElement.scrollTop >= sk.offsetTop){
header.style.top='0px'
}else{
header.style.top='-80px'
}
})
</script>
</body>
</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>Document</title>
</head>
<body>
<style>
/* 匹配带有id属性
[id]{
background:red;
}
*/
[class]{
background: red;
}
[title='aaa']{
background-color: aqua;
}
</style>
<h2 title="'aaa" >123</h2>
</body>
</html>