目录
.事件处理的三个阶段:捕获阶段、目标阶段、冒泡阶段【补充说明】
1.事件的绑定方式
DOM0级:
1.事件属性方式
<body>
<button onclick="fun1()">按钮</button>
<script>
function fun1(){
// document.querySelector('button').innerHTML='你点了它'
alert('你点了它')
}
</script>
</body>
2.赋值式
<body>
<button onclick="fun1()">按钮</button>
<button>按钮1111</button>
<script>
function fun2(){
var btn=document.querySelectorAll('button')[1]
btn.onclick=function(){
alert('这是按钮111哦')
}
}
fun2()
</script>
</body>
DOM二级:
addEventListener/attachEvent(这个在IE7 8 下使用)
<body>
<button onclick="fun1()">按钮</button>
<button>按钮1111</button>
<button>按钮2222</button>
<script>
function fun3(){
var btn=document.querySelectorAll('button')[2]
btn.addEventListener('click',function(){
alert('这是按钮222哦')
},false)
}
fun3()
</script>
2.区别:
1.事件赋值与事件监听 同事件属性相比
实现了结构与行为分离
2.事件赋值与事件监听相比
事件监听方式后面的事件不会覆盖前面的事件,按顺序执行【事件源,事件类型相同时】
<body>
<button onclick="fun1()">按钮</button>
<button>按钮1111</button>
<button>按钮2222</button>
<script>
function fun1(){
// document.querySelector('button').innerHTML='你点了它'
alert('你点了它')
}
function fun2(){
var btn=document.querySelectorAll('button')[1]
btn.onclick=function(){
alert('这是按钮111哦')
}
btn.onclick=function(){
alert('这是按钮112哦')
}
}
fun2()
function fun3(){
var btn=document.querySelectorAll('button')[2]
btn.addEventListener('click',function(){
alert('这是按钮222哦')
},false)
btn.addEventListener('click',function(){
alert('这是按钮223哦')
},false)
}
fun3()
</script>
</body>
3.事件解绑
1.赋值式
ele.οnclick=null
2.解绑事件监听
ele.removeEventListener('click',事件处理函数名)
4.事件目标对象
target:
当前鼠标选中的目标元素
兼容性处理:
e.target||e.srcElement
this关键字:在事件处理函数中,this表示事件源
5.事件传播
1.嵌套的元素,事件会传播
2.事件传播方向问题-----给元素添加事件属性
从事件目标对象开始传到window对象结束
事件冒泡:
由内往外传的时间方式【默认传播行为】
事件捕获:
由外向内传,window对象->事件目标对象
3.实现:
事件监听第三个参数设置为true表示事件捕获,否则表示事件冒泡
4.阻止事件传播
e.stopPropagation()//后面的不会执行
兼容性写法
e.stopPropagation()?e.stopPropagation():e.cancleBubble()=true
6.事件委托
事件代理:
利用事件冒泡实现的 ul->e.target->成功
事件委托使用场景:
当要给多个元素循环绑定事件的时候
<!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>事件委托</title>
<!--
事件委托
事件代理
现实生活 事件代理
点外买 -> 小哥 -> 你们
放到前台
王老师 代收
软件技术 事件代理
事件代理(委托) 利用 事件冒泡实现
事件委托使用场景
当要给多个元素循环绑定事件的时候可以考虑使用事件委托简化操作
注: 不支持事件冒泡的不能使用 如:焦点事件
好处:
减少了事件绑定的数量;
对后来动态创建的元素依然有效,
解决动态添加的元素节点无法绑定事件的问题
-->
</head>
<body>
<ul>
<li>张同学</li>
<li>李同学</li>
<li>王同学</li>
</ul>
<script>
/*
循环遍历所有同学,绑定收外买这个事情
自己的事情自己处理,没有使用代理
*/
function test1() {
var liEles = document.querySelectorAll('li')
for (var i = 0; i < liEles.length; i++) {
liEles[i].addEventListener('click', function () {
alert(this.innerHTML + '收到外买')
})
}
}
/**
* 每个同学收外买的事情,交给ul代理接收
*/
function test2(){
var ulEle = document.querySelector('ul')
ulEle.addEventListener('click',function(e){
e = e || window.event // 事件对象
var target = e.target || e.srcElement // 事件目标对象
alert(target.innerHTML + '代收到外买成功')
})
}
test2()
</script>
</body>
</html>
优点:
减少了事件绑定的数量,对后来动态创建的元素依然有效,解决动态添加的元素节点无法绑定事件的问题
减少事件的冗余绑定,节约了事件资源
缺点:
事件委托基于冒泡,对于不冒泡的事件不支持
层级过多,冒泡过程中,可能会被某层阻止掉
理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理
把所有事情都用代理就可能会出现事件误判
7.默认行为
概念:
就是不用我们注册,它自己就存在的事情
阻止默认行为:
preventDefault() ?preventDefault():returnValue=false //JavaScript:void(0)
8.函数
1.概念:实现代码的封装复用
2.定义方式
声明式:
function fun(){
函数体
}
赋值式:
btn.οnclick=function(){
//函数体
}
3.函数调用
fun()
4.自调用函数
( function(){console.log('自调用函数')} )()
9.arguments 对象
函数所有实参的集合
函数体中直接使用
类数组
作用:函数可变参数
10.this关键字
表示当前对象
在不同场景下this表示不同的对象
1.事件处理函数中的this
this->事件源
2.普通函数中的this
this->window对象
3.在定时器中的this
this->window对象
4.自调用函数中的this
this->window对象
5.对象方法中的this
this->调用该方法引用变量指向的对象
<body>
<button>确定</button>
<script>
function test1() {
var btn = document.querySelector('button')
btn.addEventListener('click', function () {
// this->事件源->button按钮
console.log('this : ', this)
})
}
function fun(){
console.log('this -> ',this)
}
// fun()
// setTimeout(function(){
// console.log('定时器 this -> ',this)
// },1000)
// (function(){
// console.log('自调用函数this -> ',this)
// })()
var obj = {
name:'jack',
say: function(){
console.log(this.name + '说话, say方法调用');
console.log('对象Object方法中this -> ',this)
}
}
obj.say()//====返回的是obj
</script>
</body>
.事件处理的三个阶段:捕获阶段、目标阶段、冒泡阶段【补充说明】
案例:
todoList的数据操作方式+事件监听绑定:
<!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>todoList</title>
</head>
<body>
<div class="container">
<input type="text" placeholder="请输入内容" /><button>确定</button>
<ul>
<!-- <li>css</li> -->
</ul>
</div>
<script>
//定义数组追加
var arr = []
//按钮绑定事件 -》获取input的输入内容-》添加到ul里面
var btn = document.querySelector('.container>button')
//展示列表
function shows() {
var ulEle = document.querySelector('.container>ul')
//遍历数组得到数组长度的li再获取下标为删除做准备用返回新数组的方法
var newArr = arr.map(function (item, index) {
return `<li data-index='${index}'>${item}</li>`
})
var arrStr = newArr.join('')
// 变为字符串
ulEle.innerHTML = arrStr
// 显示了才能删除和绑定事件
onDelete()
}
// 点击添加内容
btn.addEventListener('click', function () {
// 这个必须在这里哦
var inputEle = document.querySelector('.container>input')
var inputValue = inputEle.value
arr.push(inputValue)
// console.log(arr)
//清除input的内容
inputEle.value = ''
// arr用来存储获取的内容
// 添加后还要显示哦
shows()
}, false)
// 删除内容
function onDelete() {
// 首先选中所有li元素要获取li的下标
var lis = document.querySelectorAll('ul>li')
for (var j = 0; j < lis.length; j++) {
lis[j].addEventListener('click', function () {
//用数组的方法去掉一个元素就显示不了
// 获取下标
alert(`你正在删除${this.innerHTML}`)//这里不能用lis[j]哦
var index = this.dataset.index//当前事件的下标
console.log(this)
arr.splice(index, 1)
shows()
}, false)
}
}
// 初始化显示arr arr一开始有的内容也显示到页面
shows()
</script>
</body>
</html>
todoList的节点操作+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>todoList</title>
</head>
<body>
<div class="container">
<input type="text" placeholder="请输入内容" /><button>确定</button>
<ul>
<!-- <li>css</li> -->
</ul>
</div>
<script>
/*
1. 详细描述需求
点击确定按钮,获取输入框内容,显示到ul节点下
分析: 复杂问题简化
1. 绑定点击事件
2. 获取输入框内容
3. 创建li子节点,输入框作用子节点文本内容,追加给ul
*/
var btn = document.querySelector('button')
btn.addEventListener('click', function () {
//2. 获取输入框内容
var inputEle = document.querySelector('input')
var inputValue = inputEle.value
//3.创建li子节点,输入框作用子节点文本内容,追加给ul
var liEle = document.createElement('li')
liEle.innerHTML = inputValue // <li>css</li>
// 4. 追加元素
var ulEle = document.querySelector('ul')
ulEle.appendChild(liEle)
//5. 清空内容
inputEle.value = ''
// 6. 绑定删除事件
onDelete()
})
/*
分析: 遍历所有li绑定点击事件, 删除当前点击的元素
*/
function onDelete() {
var liEles = document.querySelectorAll('ul>li') //能不能获取li
for (var i = 0; i < liEles.length; i++) {
var liEle = liEles[i] //li元素
//绑定事件
liEle.addEventListener('click', function () {
// 删除当前点击的元素
// this关键字: 当前点击的元素节点对象
this.remove()
})
}
}
</script>
</body>
</html>