一、事件对象
1、获取事件对象
<script type="text/javascript">
// 事件对象:事件触发时产生的对象
// 记录了和事件相关的信息
// 使用事件对象
// 事件对象:在事件处理函数添加第一个形参就接受的事件对象
// 通常:e、ev、e_、ev_、event
// document.addEventListener('click', function (e) {
// console.log( e );
// });
document.addEventListener('dblclick', function (ev) {
console.log(ev);
});
</script>
2、事件对象常用属性
<div></div>
<script type="text/javascript">
// 点击div获取鼠标的位置
let div = document.querySelector('div');
// 监听事件
div.addEventListener('click', function (e) {
// 获取鼠标的位置
// 事件对象.clientX、事件对象.clientY:
// 获取鼠标距离可视窗口的位置
console.log( e.clientX,e.clientY );
// 事件对象.pageX、事件对象.pageY
// 获取鼠标距离文档的位置
console.log( e.pageX, e.pageY );
// 事件对象.offsetX,事件对象.offsetY
// 获取数据距离当前元素的位置
console.log( e.offsetX, e.offsetY );
// console.log( e.type )
});
</script>
<style type="text/css">
* {
margin: 0;padding: 0;
}
img {
width: 100px;
height: 100px;
border:1px solid red;
position: absolute;
left: 0;
top : 0;
/*cursor: text;*/
}
</style>
<img src="images/tianshi.gif">
<script type="text/javascript">
// 获取img
let img = document.querySelector('img');
// 鼠标在文档上移动,移动的时候让图片跟着鼠标移动
// mousemove:移动事件
document.addEventListener('mousemove', function (e) {
// 原理:鼠标移动的时候获取鼠标的x和y的位置
// 吧x和y分别设置给图片的left和top
let x = e.clientX;
let y = e.clientY;
// 设置给img
img.style.left = x - 50 + 'px';
img.style.top = y - 50 + 'px';
});
</script>
二、事件流
1、事件流阶段说明
2、事件捕获与冒泡
(1)事件冒泡:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件,默认存在的
(2)事件捕获:从DOM的根元素开始去执行对应的事件 (从外到里),需要对应代码才能看到
(3)阻止事件流动
鼠标经过事件: ➢ mouseover 和 mouseout 会有冒泡效果 ➢ mouseenter 和 mouseleave 没有冒泡效果(推荐
(4)事件注册
<input type="button" value="点击">
<script type="text/javascript">
// 注册事件:
// 事件源.onxxx = 函数
// 事件源.addEventListener('事件类型', 函数);
// 移除事件:
// 事件源.onxxx = null
// 事件源.removeEventListener('事件类型', 函数名);
// 获取元素:
let btn = document.querySelector('input');
// 区别:
// on:
// 同类型的事件on只能注册1个
// 不可以开启捕获
// 事件源.onxxx = null;
// addEventListener:
// 同类型的事件可以注册多个
// 给第三个参数加true,可以开启捕获
// 事件源.removeEventListener('事件类型', 函数名)
// 注册事件
// btn.onclick = function () {
// console.log(1);
// }
// // 移除事件:
// btn.onclick = null;
// btn.onclick = function () {
// console.log(2);
// }
// btn.onclick = function () {
// console.log(3);
// }
// let f1 = function () {
// console.log('a');
// }
function f1 () {
console.log('a');
}
let f2 = function () {
console.log('b');
}
let f3 = function () {
console.log('c');
}
btn.addEventListener('click', f1);
btn.addEventListener('click', f2);
btn.addEventListener('click', f3);
// 移除事件
// 事件源.removeEventListener('事件类型', 事件处理函数名);
btn.removeEventListener('click', f1);
// btn.removeEventListener('click', f2);
// btn.removeEventListener('click', f3);
</script>
三、事件委托
<style type="text/css">
ul li {
border: 1px solid #ccc;
margin: 10px;
height: 30px;
}
</style>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10<a href="#">链接</a>></li>
</ul>
<script type="text/javascript">
// 获取元素
// let lis = document.querySelectorAll('li');
let ul = document.querySelector('ul');
// 事件委托:把事件委托给上级元素
// 实现事件委托:
// 1、把事件注册给上级元素
// 2、利用事件对象.target找到最先触发事件的元素
// 3、用nodeName判断这个元素是否是我们需要的
ul.addEventListener('click', function (e) {
// e.target有可能是我们要找的元素也有可能不是我们要找的元素
// 如果e.target是我们要找的元素,再加背景色
if ( e.target.nodeName === 'LI' ) {
e.target.style.background = 'blue';
}
});
let newLi = document.createElement('li')
newLi.innerHTML = '新的li'
ul.appendChild(newLi)
// 遍历添加事件
// for ( let i = 0; i < lis.length; i++ ) {
// lis[i].onclick = function () {
// this.style.background = 'red';
// }
// }
// lis[0] = 函数
// lis[1] = 函数
// lis[2] = 函数
// ......
</script>
四、案例
1、渲染学生信息
数据驱动视图
<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="stuId">
薪资:<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>1001</td>
<td>欧阳霸天</td>
<td>19</td>
<td>男</td>
<td>15000</td>
<td>上海</td>
<td>
<a href="javascript:">删除</a>
</td>
</tr> -->
</tbody>
</table>
<script>
// 1. 准备好数据后端的数据
let arr = [
{ stuId: 1001, uname: '欧阳霸天', age: 19, gender: '男', salary: '20000', city: '上海' },
{ stuId: 1002, uname: '令狐霸天', age: 29, gender: '男', salary: '30000', city: '北京' },
{ stuId: 1003, uname: '诸葛霸天', age: 39, gender: '男', salary: '2000', city: '北京' },
];
// 获取元素
let uname = document.querySelector('.uname');
let age = document.querySelector('.age');
let gender = document.querySelector('.gender');
let stuId = document.querySelector('.stuId');
let salary = document.querySelector('.salary');
let city = document.querySelector('.city');
let add = document.querySelector('.add');
let tbody = document.querySelector('tbody');
// 1、展示数据
showMessage();
function showMessage () {
// 在展示数据之前清除数据
tbody.innerHTML = '';
// 展示数据
for ( let i = 0; i < arr.length; i++ ) {
// arr[i]是对象、一个对象对应一个tr
// console.log( arr[i] );
let tr = document.createElement('tr');
// 放到tbody
tbody.appendChild(tr);
// 设置内容
tr.innerHTML = `<td>${arr[i].stuId}</td>
<td>${arr[i].uname}</td>
<td>${arr[i].age}</td>
<td>${arr[i].gender}</td>
<td>${arr[i].salary}</td>
<td>${arr[i].city}</td>
<td>
<a href="javascript:;" id="${i}">删除</a>
</td>`;
}
}
// 2、添加数据
add.addEventListener('click', function () {
// 添加
arr.push( {
stuId : arr[arr.length - 1].stuId + 1,
uname : uname.value,
age : age.value,
gender : gender.value,
salary : salary.value,
city : city.value,
} );
// console.log( arr );
// 调用函数展示
showMessage();
// 恢复表单
uname.value = '';
age.value = '';
gender.value = '男';
salary.value = '';
city.value = '北京';
});
// 3、刪除数据
tbody.addEventListener('click', function (e) {
if ( e.target.nodeName === 'A' ) {
// 以数据为准
// a带有数据的索引值
arr.splice( e.target.id, 1);
// console.log(arr);
showMessage();
}
});
</script>
</body>
\