一、事件的绑定方式
DOM0级
1.事件属性方式
2.赋值式
DOM2级
3.事件监听
element.addEventListener('事件类型',function(){ })
兼容性问题(兼容IE7、8)
ele.attachEvent(事件类型,事件处理函数)
注意:事件类型前加“on” ,onclick
区别:
1.事件赋值与事件监听 和 事件属性相比,实现了结构与行为分离
2.事件赋值与事件监听
事件监听方式,后面的事件不会覆盖前面的事件(事件源和事件类型相同)。
事件解绑:
1.解绑赋值式绑定事件
ele.onclick = null
2.解绑事件监听
ele.removeEventListener('click',事件处理函数)
<!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>事件的绑定方式</title>
</head>
<body>
<button onclick="alert()">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<script>
var btn2 = document.querySelectorAll('button')[1]
btn2.onclick = function(){
alert('事件赋值1') //会被覆盖
}
btn2.onclick = function(){
alert('事件赋值2')
}
// 事件监听写法
var btn3 = document.querySelectorAll('button')[2]
btn3.addEventListener('click',function(){
alert('事件监听1') //先
})
btn3.addEventListener('click',function(){
alert('事件监听2') //后
})
/*
function fun1(){
alert('事件监听1') //先
}
function fun2(){
alert('事件监听2')
}
btn3.addEventListener('click',fun1)
btn3.addEventListener('click',fun2)
//解绑事件监听
// btn3.removeEventListener('click',fun1)
*/
</script>
</body>
</html>
二、事件目标对象
事件目标对象:target
当前选中的元素节点
e.target
兼容IE
e.srcElement
var target = e.target || e.srcElement
this关键字:在事件处理函数中this表示事件源
console.log('this ',this)
<!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>事件目标对象</title>
<style>
div{
width: 100px;
height: 100px;
background-color: #a00;
}
p{
width: 50px;
height: 50px;
background-color: #00a;
}
</style>
</head>
<body>
<div>
<p></p>
</div>
<script>
var divEle = document.querySelector('div')
divEle.addEventListener('click',function(e){
e = e || window.event //事件对象
var target = e.target || e.srcElement //事件目标对象
console.log('target ',target)
})
</script>
</body>
</html>
三、事件传播
1. 嵌套的元素,事件会传播
2. 事件传播方向问题
+ 事件冒泡
从事件目标对象开始 -> window对象结束
由内向外传播的事件方式称为事件冒泡 (默认传播行为)
+ 事件捕获
由外向内传, window对象 -> 事件目标对象
3. 事件监听第三个参数设置true表示事件捕获,默认false表示事件冒泡
4. 阻止事件传播:e.stopPropagation()
兼容ie浏览器写法:e.cancelBubble = true
e.stopPropagation?e.stopPropagation():e.cancelBubble = true
<!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>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
div {
width: 200px;
height: 200px;
background-color: skyblue;
margin: 100px;
}
p {
width: 100px;
height: 100px;
background-color: pink;
}
h4 {
width: 150px;
height: 150px;
background-color: blueviolet;
}
</style>
</head>
<body>
<div>
<h4>
<p></p>
</h4>
</div>
<script>
var divEle = document.querySelector('div')
var h4Ele = document.querySelector('h4')
var pEle = document.querySelector('p')
divEle.addEventListener('click',function(e){
e = e || window.event
var target = e.target || e.srcElement //事件目标对象
console.log('div对象',target)
},false) //默认false表示事件冒泡
pEle.addEventListener('click',function(e){
console.log('p元素')
},false)
h4Ele.addEventListener('click',function(e){
e.stopPropagation?e.stopPropagation():e.cancelBubble = true //阻止事件向上传播,点击h4的区域不会在控制台打印p
console.log('h4元素')
},false)
</script>
</body>
</html>
四、事件委托
现实生活中,快递代收算是一个事件代理(委托);软件世界中,事件代理(委托) 利用事件冒泡实现(由内向外)。
事件委托使用场景:当要给多个元素循环绑定事件的时候可以考虑使用事件委托简化操作。
注意: 不支持事件冒泡的不能使用,如:焦点事件。
好处:
- 减少了事件绑定的数量
- 对后来动态创建的元素依然有效
- 解决动态添加的元素节点无法绑定事件的问题
<!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>事件委托</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>
五、默认行为
1. a标签 默认行为:href执行链接跳转
2. form表单action,把表单内容提交到地址栏并且刷新页面
3. 右键事件contextmenu,按右键会出现一个功能菜单
阻止默认行为:e.preventDefault()
扩展(阻止a标签默认事件的另一种方法):
<a href="javascript:void(0)" >确定</a>
<!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>默认行为</title>
</head>
<body>
<a href="">按钮</a>
<!-- <a href="javascript:void(0)">确定</a> -->
<div>
<form>
<input type="text" placeholder="请输入内容" name="message"><br>
<input type="submit" value="提交">
</form>
</div>
<script>
function test1() {
var aEle = document.querySelector('a')
aEle.addEventListener('click', function (e) {
e = e || window.event
e.preventDefault() // 阻止a标签默认行为
alert('事件监听a标签')
})
}
function test2(){
var formEle = document.querySelector('form')
formEle.addEventListener('submit',function(e){
e = e || window.event // 事件对象
e.preventDefault() // 阻止a标签默认行为
alert('表单提交事件')
})
}
test2()
function test3(){
document.addEventListener('contextmenu',function(e){
e = e || window.event // 事件对象
e.preventDefault() // 阻止a标签默认行为
alert('右键事件')
})
}
test3()
</script>
</body>
</html>
六、函数补充
我们简单回顾一下函数:
作用:任意功能代码封装。
定义方式:
1. 声明式
function getMax(){
//封装代码
}
2. 函数表达式
var getMax = function(){
}
函数调用语句:getMax()
回顾完毕,补充一些函数相关的:
自调用函数:函数定义和调用写在一块。
(function(){
// 函数体
})()
作用:封装代码;封装私有变量,独立于全局变量。
arguments 对象
=> 函数所有实参的集合
=> 函数体中直接使用
=> 类数组
=> 函数可变参数
<!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>函数</title>
</head>
<body>
<script>
(function(){
alert('自调用函数')
var num = 100
})()
function fun(){
// arguments 类数组形式存在
console.log(arguments)
for(var i = 0; i < arguments.length; i++){
console.log(arguments[i])
}
}
// fun(10,20,30) //函数调用,输出所有实参,不管有没有形参
// arguments示例:计算任意数总和
function sum(){
var s = 0
for(var i = 0; i < arguments.length; i++){
s = s + arguments[i]
}
return s
}
var s = sum(10,20,30,50)
alert(s)
</script>
</body>
</html>
七、this关键字
this表示当前对象;在同场景下this表示不同的对象
1. 事件处理函数中的this
this->事件源
2. 普通函数中this
this -> window对象
3. 定时器中this
this -> window对象
4. 自调用函数中this
this -> window对象
5. 对象方法中的this
Object
var obj = {
name:'jack',
say:function(){
this
}
}
调用该方法引用变量指向的对象
<!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>this关键字</title>
</head>
<body>
<button>确定</button>
<script>
function test1() {
var btn = document.querySelector('button')
btn.addEventListener('click', function () {
// this->事件源->button按钮
console.log('this : ', this)
})
}
test1()
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()
</script>
</body>
</html>