当前位置:网站首页>JS7day(事件对象,事件流,事件捕获和冒泡,阻止事件流动,事件委托,学生信息表案例)
JS7day(事件对象,事件流,事件捕获和冒泡,阻止事件流动,事件委托,学生信息表案例)
2022-07-02 09:43:00 【荻风溪畔】
文章目录
事件对象
获取事件对象
事件对象是什么?
也是个对象,这个对象里有事件触发时的相关信息
例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息如何获取?
在事件绑定的回调函数的第一个参数就是事件对象
一般命名为event
、ev
、e
部分常用属性
type
获取当前的事件类型clientX
/clientY
获取光标相对于浏览器可见窗口左上角的位置offsetX
/offsetY
获取光标相对于当前DOM元素左上角的位置key
用户按下的键盘键的值
现在不提倡
使用keyCode
(已废弃)
img {
position: absolute;
top: 0;
left: 0;
}
img要用到绝对定位
<img src="./images/tianshi.gif" alt="">
<script>
let img = document.querySelector('img')
document.addEventListener('mousemove', function (e) {
// 不断得到当前的鼠标坐标
// 把坐标给图片(别忘了单位)
// img.style.left = '100px'
img.style.left = e.pageX - 50 + 'px'
img.style.top = e.pageY - 40 + 'px'
})
加上代码:
area.addEventListener('keyup', function (e) {
//不要用keydown,键盘弹起的时候,再执行否则area里会接受enter字符,导致area.value=1
if (e.key == 'Enter') {
//是enter键才行
send.click()
}
})
事件流
- 事件流指的是事件完整执行过程中的流动路径:先捕获后冒泡
事件捕获概念:
从DOM的根元素开始去执行对应的事件 (从外到里)
- 事件捕获需要写对应代码才能看到效果
- 代码:
DOM.addEventListener(时间类型,事件处理函数,是否使用捕获机制)
- 说明:
addEventListener
第三个参数传入true
代表是捕获阶段触发(很少使用
)
若传入false
代表冒泡阶段触发,默认就是false
若是用 L0 事件监听,则只有冒泡阶段,没有捕获
事件冒泡概念:
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
事件冒泡是默认存在的
案例:
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
son.addEventListener('click', function () {
alert('我是儿子')
})
fa.addEventListener('click', function () {
alert('我是爸爸')
})
</script>
点击儿子区域,依次弹出:我是儿子,我是爸爸(传入true,则相反)
阻止事件流动:
因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
- 若想把事件就限制在当前元素内,就需要阻止事件流动
- 阻止事件流动需要拿到事件对象
- 语法:
事件对象.stopPropagation()
- 此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
示例:
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('click', function () {
alert('我是爸爸')
})
son.addEventListener('click', function (e) {
alert('我是儿子')
e.stopPropagation()
})
</script>
点击儿子区域,只弹出:我是儿子。
相同的鼠标经过事件:
mouseover
和 mouseout
会有冒泡效果
mouseenter
和 mouseleave
没有冒泡效果(推荐)
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('mouseover', function () {
console.log(111)
})
</script>
鼠标在父元素内,在父元素和子元素之间移动,会不断输出:111(改成mousenter
就好了)
两种(监听事件)注册事件的区别:
传统on注册(L0)
- 同一个对象,后面注册的事件会覆盖前面注册的事件(同一个事件)
- 直接
=null
(比如btn.onclick=null
),就可以实现事件的解绑 - 都是冒泡阶段执行的
事件监听注册(L2)
- 语法:
addEventListener
(事件类型, 事件处理函数, 是否使用捕获) - 后面注册的事件不会覆盖前面注册的事件(同一个事件)
- 可以通过第三个参数去确定是在冒泡或者捕获阶段执行
- 如果要事件解绑,必须使用
removeEventListener
(事件类型, 事件处理函数, 获取捕获或者冒泡阶段) - 匿名函数无法被解绑
btn.addEventListener('click', add)
function add() {
//给函数起名字,匿名函数无法解绑
alert('第一次')
}
btn.removeEventListener('click', add)
事件委托
事件委托是利用事件流的特征解决一些开发需求的知识技巧
总结:
- 优点:给父级元素加事件(可以提高性能)
- 原理:事件委托其实是利用事件冒泡的特点
- 实现:
事件对象.target
可以获得真正触发事件的元素
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
let ul = document.querySelector('ul')
ul.addEventListener('click', function (e) {
(e.target.style.color = 'red') //核心
})
</script>
学生信息表案例
难点在于删除怎么写,要用到事件委托,也就是监听整个大的tbody
,在寻找点击的删除属于tbody
中的哪一行数据。
如果用笨方法给每行添加监听,很难实现,而且性能不好。
没有想到用e.target.tagName
判断点击的是不是删除元素。还有给a加个id进行标记id="${i}"
来删除数组。
js代码:
// 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: '北京'},
]
// 获取父元素 tbody
let tbody = document.querySelector('tbody')
// 添加数据按钮
// 获取录入按钮
let add = document.querySelector('.add')
// 获取各个表单的元素
let uname = document.querySelector('.uname')
let age = document.querySelector('.age')
let gender = document.querySelector('.gender')
let salary = document.querySelector('.salary')
let city = document.querySelector('.city')
// 渲染函数 把数组里面的数据渲染到页面中
function render() {
// 先干掉以前的数据 让tbody 里面原来的tr 都没有
tbody.innerHTML = ''
// 在渲染新的数据
// 根据数据的条数来渲染增加 tr
for (let i = 0; i < arr.length; i++) {
// 1.创建tr
let tr = document.createElement('tr')
// 2.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> `
// 3.把tr追加给 tobdy 父元素.appendChild(子元素)
tbody.appendChild(tr)
}
}
// 页面加载就调用函数
render()
add.addEventListener('click', function () {
// alert(11)
// 获得表单里面的值 之后追加给 数组 arr 用 push方法
arr.push({
// 得到数组最后一条数据的学号 1003 + 1
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)
// 重新渲染我们的函数
render()
// 复原所有的表单数据
uname.value = age.value = salary.value = ''
gender.value = '男'
city.value = '北京'
})
// 删除操作, 删除的也是数组里面的数据 , 但是我们用事件委托(难点!!!)
tbody.addEventListener('click', function (e) {
// alert(11)
// 我们只能点击了链接 a ,才会执行删除操作
// 那我们怎么知道你点击了a呢?
// 俺们只能点击了链接才能做删除操作
// console.dir(e.target.tagName)
if (e.target.tagName === 'A') {
// alert('你点击了链接')
// 删除操作 删除 数组里面的数据 arr.splice(从哪里开始删,1) 给a加个id进行标记id="${i}"
// 我要得到a的id 需要
// console.log(e.target.id)
arr.splice(e.target.id, 1)
// 重新渲染我们的函数
render()
}
})
边栏推荐
- (C language) 3 small Codes: 1+2+3+ · · +100=? And judge whether a year is a leap year or a normal year? And calculate the circumference and area of the circle?
- IPhone 6 plus is listed in Apple's "retro products" list
- 接口测试面试题目,你都会了吗?
- High performance erasure code coding
- Input a three digit number and output its single digit, ten digit and hundred digit.
- drools执行指定的规则
- 分布式机器学习框架与高维实时推荐系统
- Go learning notes - go based interprocess communication
- Interview with meituan, a 34 year old programmer, was rejected: only those under the age of 30 who work hard and earn little overtime
- Leetcode - Sword finger offer 51 Reverse pairs in an array
猜你喜欢
[old horse of industrial control] detailed explanation of Siemens PLC TCP protocol
Lekao: 22 year first-class fire engineer "technical practice" knowledge points
Simple understanding of ThreadLocal
drools动态增加、修改、删除规则
Use sqoop to export ads layer data to MySQL
spfa AcWing 852. spfa判断负环
Discrimination of the interval of dichotomy question brushing record (Luogu question sheet)
包管理工具
This "little routine" is set on the dough cake of instant noodles. No wonder programmers are always hungry
[C language] convert decimal numbers to binary numbers
随机推荐
Go学习笔记—多线程
Discrimination of the interval of dichotomy question brushing record (Luogu question sheet)
What data types does redis have and their application scenarios
Day12 control flow if switch while do While guessing numbers game
Lombok common annotations
上传文件时,服务器报错:IOFileUploadException: Processing of multipart/form-data request failed. 设备上没有空间
Introduction to CPU instruction set
包管理工具
Sort---
分布式机器学习框架与高维实时推荐系统
Lekao: 22 year first-class fire engineer "technical practice" knowledge points
Input box assembly of the shutter package
怎样写一篇赏心悦目的英文数学论文
Simple understanding of ThreadLocal
Sparkcontext: error initializing sparkcontext solution
Leetcode - < dynamic planning special> Jianzhi offer 19, 49, 60
[C language] Yang Hui triangle, customize the number of lines of the triangle
Docker-compose配置Mysql,Redis,MongoDB
Why do programmers have the idea that code can run without moving? Is it poisonous? Or what?
线性DP AcWing 899. 编辑距离