事件对象
事件对象是什么
也是个对象,但是这个对象包含事件触发时的相关信息,例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
如何获取
在事件绑定的回调函数的第一个参数就是事件对象,一般命名为event、ev、e
部分常用属性
type:获取当前的事件类型
clientX/clientY:获取光标相对于浏览器可视窗口左上角的位置
offsetX/offsetY:获取光标相对于当前DOM/自身元素左上角的位置
key:用户按下的键盘键的值(现在不提倡使用keyCode)
事件流
事件流与两个阶段说明
事件流指的是事件完整执行过程中的流动路径。简单来说:捕获阶段是从父到子 ,冒泡阶段是从子到父
事件捕获和事件冒泡
捕获阶段
从DOM的根元素开始去执行对应的事件,addEventListener第三个参数传入true代表是捕获阶段触发(一般很少使用)
a.addEventListener('click', function () {
console.log('a');
}, true); // 捕获
冒泡阶段
当一个元素触发事件后,会依次向上调用所有父级元素的同名事件,事件冒泡是默认存在的
c.addEventListener('click',function () {
console.log('c');
},false) //冒泡 默认不用设置
阻止事件流动
因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素,若想把事件就限制在当前元素内,就需要阻止事件流动(需要拿到事件对象)
son.addEventListener('click',function (e) {
console.log('son');
// 阻止事件捕获和冒泡 影响父级
e.stopPropagation()
},
阻止默认行为
阻止默认行为,比如a标签的点击跳转,form表单中button点击刷新行为
a.addEventListener("click",function (event) {
console.log("a标签的点击触发啦");
// 阻止a标签的默认行为,让他不要跳转
event.preventDefault();
})
form.addEventListener("submit",function (event) {
// 不要让页面再刷新
event.preventDefault();
})
button.addEventListener("click",function (event) {
event.preventDefault(); // 不要让页面再刷新
})
常见的两种阻止默认行为
1 a标签的点击跳转
2 form表单中button点击刷新行为
1 阻止默认行为 - form表单 有一个 submit 事件 理解提交表单的触发-点击按钮的时候触发
2 给button按钮绑定点击事件 也去阻止试试
3 给button按钮 添加一个 type="button" 属性
4 换成 input标签 type="button"
5 把button 移出form表单的区域
事件委托
**原理:**当你想要给一组标签绑定事件实现业务时, 我们可以把事件绑定给父元素上 ,通过事件委托给父元素来做
优点:提高性能
实现:事件对象.target 可以获得真正触发事件的元素
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
const ul =document.querySelector('ul')
ul.addEventListener('click',function (e) {
// event.target 你当前点击的是哪个标签(点击最深最底层的那个标签)
// event.target 有可能是ul标签,有可能是li标签,还有可能是 a标签 在ul标签内元素都能触发
e.target.style.color = 'red' // 太过笼统,不够具体,不够完美
})
</script>
</body>
指定标签
<body>
<ul>
<li>1 <a href="#"> 我是a1</a></li>
<li>2 <a href="#"> 我是a2</a></li>
<li>3 <a href="#"> 我是a3</a></li>
<li>4 <a href="#"> 我是a4</a></li>
<li>5 <a href="#"> 我是a5</a></li>
<li>6 <a href="#"> 我是a6</a></li>
</ul>
<script>
const ul = document.querySelector('ul')
ul.addEventListener('click',function (e) {
// e.target.nodeName === 'A' 当前点击的元素的标签名 大写字母
if (e.target.nodeName === 'A') {
e.target.style.color = 'pink' // 只有点击a标签才会触发
}
})
</script>
</body>
综合案例---渲染学生信息案例
实现思路
案例实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>08-综合案例-模版</title>
<style>
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
color: #721c24;
}
h1 {
text-align: center;
color: #333;
margin: 20px 0;
}
table {
margin: 0 auto;
width: 800px;
border-collapse: collapse;
color: #004085;
}
th {
padding: 10px;
background: #cfe5ff;
font-size: 20px;
font-weight: 400;
}
td,
th {
border: 1px solid #b8daff;
}
td {
padding: 10px;
color: #666;
text-align: center;
font-size: 16px;
}
tbody tr {
background: #fff;
}
tbody tr:hover {
background: #e1ecf8;
}
.info {
width: 900px;
margin: 50px auto;
text-align: center;
}
.info input {
width: 80px;
height: 25px;
outline: none;
border-radius: 5px;
border: 1px solid #b8daff;
padding-left: 5px;
}
.info button {
width: 60px;
height: 25px;
background-color: #004085;
outline: none;
border: 0;
color: #fff;
cursor: pointer;
border-radius: 5px;
}
.info .age {
width: 50px;
}
</style>
</head>
<body>
<h1>新增学员</h1>
<div class="info">
姓名:<input type="text" class="uname" /> 年龄:<input type="text" class="age" />
性别:
<select name="gender" id="" class="gender">
<option value="男">男</option>
<option value="女">女</option>
</select>
薪资:<input type="text" class="salary" /> 就业城市:<select name="city" id="" class="city">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
<option value="曹县">曹县</option>
</select>
<button class="add">录入</button>
</div>
<h1>就业榜</h1>
<table>
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>薪资</th>
<th>就业城市</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- <tr>
<td>1</td>
<td>这是名称</td>
<td>这是年龄</td>
<td>这是性别</td>
<td>这是工资</td>
<td>这是所在城市</td>
<td>
<a href="javascript:" class="del">删除</a>
</td>
</tr> -->
</tbody>
</table>
<script>
// 定义数组 负责存放表格要显示的数据
let arr = []
// 1.拼接字符串
// 获取dom元素
const tbody = document.querySelector('tbody')
const add = document.querySelector('.add')
const uname = document.querySelector('.uname')
const age = document.querySelector('.age')
const gender = document.querySelector('.gender')
const salary = document.querySelector('.salary')
const city = document.querySelector('.city')
// 根据数组渲染页面
getHtml()
// 绑定添加按钮点击事件 实现数据的新增
add.addEventListener('click', function () {
// 声明一个对象来获取用户输入的值
let user = {
// 获取表单元素的值 点击事件生效获取
stuId: arr.length > 0 ? arr[arr.length - 1].stuId + 1 : 1001,
uname: uname.value,
age: age.value,
gender: gender.value,
salary: salary.value,
city: city.value,
}
// 2.将生成的对象添加到数组
arr.push(user)
// 当数组发生改变时 重新调用渲染页面的函数 省去了下面步骤
getHtml()
// let tr = document.createElement('tr')
// tr.innerHTML = `
// <td>${user.stuId}</td>
// <td>${user.uname}</td>
// <td>${user.age}</td>
// <td>${user.gender}</td>
// <td>${user.salary}</td>
// <td>${user.city}</td>
// <td>
// <a href="javascript:" class="del">删除</a>
// </td>
// `
// 点击后恢复初始值
Math.round(Math.random() * (1000 - 1) + 1),
uname.value = ''
age.value = ''
gender.value = '男'
salary.value = ''
city.value = '北京'
})
// tbody绑定点击事件,同时判断被点击的是不是 del 删除标签
tbody.addEventListener('click', function (e) {
// 3.1 判断当前点击的是不是a标签 或者类名
// 获取到a标签 上存放的 index
// event.target = a标签的dom元素
if (event.target.nodeName === 'A') {
// console.log(e.target);
// <a data-index="2" href="javascript:" class="del">删除</a>
// data-index="2" 自定义属性写法 固定搭配
// dom.dataset.index(可以随意更改) 获取标签的自定义属性 方便后期事件触发了 获取之前存的数据,比如index
const index = event.target.dataset.index;
// 3.3 执行数组删除元素
arr.splice(index, 1);
// 数组发生改变 重新渲染页面
getHtml()
}
})
// 函数动态生成标签
function getHtml() {
let tbodyHtml = ''
// 遍历数组
for (let index = 0; index < arr.length; index++) {
// 拼接字符串
tbodyHtml += `
<tr>
<td>${arr[index].stuId}</td>
<td>${arr[index].uname}</td>
<td>${arr[index].age}</td>
<td>${arr[index].gender}</td>
<td>${arr[index].city}</td>
<td>${arr[index].salary}</td>
<td>
<a data-index="${index}" href="javascript:" class="del">删除</a>
</td>
</tr>`
}
tbody.innerHTML = tbodyHtml
}
</script>
</body>
</html>
拓展
forEach的使用
const arr = [43,523,6,865,1123,452,321]
arr.forEach(function (value,index) {
console.log(value,index); // 输出结果:value:43(值) index:0(索引)
})
forEach方法的使用:它可以遍历数组,要求传入一个回调函数
语法:数组.forEach(function (value,index) {操作})
value:代表当前遍历到的数组的元素/值
index:当前元素/值所对应的索引
注意:(function ()里面的两个值的顺序用于不能变,也不能少
如果遍历的是数据/数组,那么参数名称一般为value/v,index/i
如果遍历的是元素伪数组,那么参数名称一般为ele/element
不能在里面使用continue 会报错