<!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 checks = document.querySelectorAll('.ck');
// 全选 >> 子复选框选中
checkAll.addEventListener('click', function(){
for(let i = 0; i < checks.length; i++){
checks[i].checked = this.checked;
}
});
// 子复选框都选中 >> 子复选框选中
for(let i = 0; i < checks.length; i++){
checks[i].addEventListener('click', function(){
checkAll.checked = document.querySelectorAll('.ck:checked').length === checks.length;
});
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<style>
.ck:checked{
width: 20px;
height: 20px;
}
</style>
</head>
<body>
<input type="checkbox" id="" name class="ck" />
<input type="checkbox" id="" name class="ck" />
<input type="checkbox" id="" name class="ck" />
<input type="checkbox" id="" name class="ck" />
</body>
</html>
阻止事件冒泡案例:
<body>
<!--测试冒泡效果-->
<div class="father">
我是父亲
<div class="son">
我是儿子
</div>
</div>
<script>
/* 效果说明:我是儿子就会弹出我是儿子,点击我是父亲因为没有禁用冒泡,
同样的事件就会在父元素发生(此处是点击事件),先弹出我是爸爸,再弹出我是爷爷
*/
const f = document.querySelector('.father');
const s = document.querySelector('.son');
document.addEventListener('click', function(){
alert('我是爷爷');
});
f.addEventListener('click', function(){
alert('我是爸爸');
});
s.addEventListener('click', function(e){
alert('我是儿子');
e.stopPropagation();
});
</script>
</body>
我们还可以阻止元素默认行为
<!--测试阻止元素的默认行为-->
<form action="http://www.baidu.com/">
<input type="submit" value="提交"/>
</form>
<script>
const form = document.querySelector('form');
form.addEventListener('click', function(e){
e.preventDefault();
});
</script>
演示两种方式解绑事件
- 采用 on事件方式绑定的
<!--正常点击按钮会弹出 点击了 的弹框,解绑后点击按钮没有任何效果-->
<button class="btn">按钮</button>
<script>
// 说明了 on 方式注册的事件可以被覆盖
const btn = document.querySelector('.btn');
btn.onclick = function(){
alert('点击了');
}
btn.onclick = null;
</script>
- 采用 addEventListener 方式注册的事件,必须通过 removeEventListener 的方式解绑
<button class="btn">按钮</button>
<script>
const btn = document.querySelector('.btn');
// 需要注意,如果是采用匿名函数注册的事件则无法解绑
function fn(){
alert('点击了');
}
btn.addEventListener('click', fn);
btn.removeEventListener('click', fn);
</script>
补充知识点: 通过 mouseenter、mouseleave 的鼠标经过事件没有冒泡,采用 mouseover、mouseout 的鼠标经过事件会有冒泡事件
如果我们想批量给子元素注册事件,就可以通过事件委托来完成
<!--事件委托就是利用父元素实现批量给子元素注册事件-->
<ul class="f">
<li class="son">点击</li>
<li class="son">点击</li>
<li class="son">点击</li>
<li class="son">点击</li>
<li class="son">点击</li>
</ul>
<script>
const f = document.querySelector('.f');
f.addEventListener('click', function(e){
// 注意,此处需要大写
if(e.target.tagName === 'LI'){
alert('事件注册成功');
}
});
</script>
<!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="tab00.png" alt="" /></div>
<div class="item"><img src="tab01.png" alt="" /></div>
<div class="item"><img src="tab02.png" alt="" /></div>
<div class="item"><img src="tab03.png" alt="" /></div>
<div class="item"><img src="tab04.png" alt="" /></div>
</div>
</div>
<!--就是给两个 div 注册事件-->
<script>
// 最好找到直接父标签
const ul = document.querySelector('.tab-nav ul');
const items = document.querySelectorAll('.tab-content .item');
ul.addEventListener('click', function(e){
// 标签应该精确一些
if(e.target.tagName === 'A'){
// 先去掉之前存在的 active(是先查询出其中有active的再删除),再给当前的添加
document.querySelector('.tab-nav .active').classList.remove('active');
e.target.classList.add('active');
}
// 为什么点击标签就能和图片关联起来呢,因为将联动设计在同一个点击事件里
/*
target.dataset 的作用就是取出标签中 data 开头的元素值,比如:data-id 用 target.dataset.id 来取,利用下标关系建立对应关系
*/
let id = +e.target.dataset.id;
document.querySelector('.tab-content .active').classList.remove('active');
items[id].classList.add('active');
});
</script>
</body>
</html>
在自己练习的时候图片可以任选
两种页面加载方式
<!--页面加载 load-->
<script>
// 对于整个页面加载
window.addEventListener('load', function(){
alert('全局页面加载完成!');
});
// 对于整个文档加载完成后会触发 DOMContentLoaded 事件,无需等待图片、CSS样式加载完成
document.addEventListener('DOMContentLoaded', function(){
alert('全局文档加载完成!');
});
// 测试效果,先弹出 文档加载完成,再弹出页面加载完成 >> 主要作用可以获取元素位置、页面初始化等操作
</script>
下面是一个案例,页面中有一段文字,当页面滚动到一定位置才会显现出来,利用控制元素的style在none和block之间完成切换
<!DOCTYPE html>
<html>
<head>
<style>
body {
padding-top: 100px;
height: 3000px;
}
div {
display: none;
margin: 100px;
overflow: scroll;
width: 200px;
height: 200px;
border: 1px solid #000;
}
</style>
</head>
<body>
<!--页面滚动时间 scroll-->
<div >
为了显示很多行,所以给 div 设置大小边框,并准备很多文字;
为了显示很多行,所以给 div 设置大小边框,并准备很多文字;为了显示很多行,所以给 div 设置大小边框,并准备很多文字
为了显示很多行,所以给 div 设置大小边框,并准备很多文字;为了显示很多行,所以给 div 设置大小边框,并准备很多文字;为了显示很多行,所以给为了显示很多行,所以给 div 设置大小边框,并准备很多文字
为了显示很多行,所以给 div 设置大小边框,并准备很多文字;为了显示很多行,所以给 div 设置大小边框,并准备很多文字
为了显示很多行,所以给 div 设置大小边框,并准备很多文字;为了显示很多行,所以给为了显示很多行,所以给 div 设置大小边框,并准备很多文字
为了显示很多行,所以给 div 设置大小边框,并准备很多文字;为了显示很多行,所以给 div 设置大小边框,并准备很多文字
</div>
<script>
const div = document.querySelector('div');
window.addEventListener('scroll', function(){
// 打印页面滚动了多少像素
console.log(document.documentElement.scrollTop);
// 打印我们的 div 被卷进去多少像素
console.log(div.scrollTop);
console.log('**********************');
let scrollTop = document.documentElement.scrollTop;
if(scrollTop <= 100){
div.style.display='none';
}else{
div.style.display='block';
}
});
</script>
</body>
</html>
我们查看一下打印细节
<script>
// 看看获取到的是什么数据 >> 没有单位 >> 测试发现此时直接进入页面会打印两条数据 800 100
/*
猜测,因为指定了滚动距离,所以在一进入页面就会有滚动事件发生,此时该参数的值为 800所以打印800;
然后实际页面卷入进去的长度为 100,所以打印100
*/
document.documentElement.scrollTop = 800;
window.addEventListener('scroll', function(){
console.log(document.documentElement.scrollTop);
});
</script>