事件
了解事件
在页面中所做事情的描述
+ 我们提前和浏览器约定好一些行为
+ 当用户在浏览器触发这些行为的时候,有一个事件处理函数执行
事件三要素
1. 事件源: 在谁的身上绑定事件
2. 事件类型: 什么事件
3. 事件处理函数: 当行为发生的时候,执行哪一个函数
+ div.onclick = function(){}
-> div: 事件源(绑定在 div 身上的事件)
-> click: 事件类型
-> function(){}: 事件处理函数
-> on: 绑定事件的方式
事件绑定分类
1. dom0级 事件
+ on...的形式
2. dom2级 事件
+ 事件监听
<style>
div{
width: 100px;
height: 100px;
background-color: pink;
}
</style>
<div></div>
// 0. 获取元素
var div = document.querySelector('div')
// 1. 绑定事件
div.onclick = function(){
console.log('我被点击了')
}
事件的绑定
1. dom0级 事件
+ 元素.onclick = function(){}
// 0. 获取元素
// var div = document.querySelector('div')
var div = document.getElementById('box')
// 1. dom0级事件
div.onclick = function(){console.log('我被点击了')}
div.onclick = function(){console.log('hello world')}
注: 相当于赋值, 所以第二次的function会覆盖第一次的function.
2. dom2级 事件
2-1. addEventListener()
=> 标准浏览器使用
=> 语法: 元素.addEventListerner('事件类型', 事件处理函数)
=> 可以同时给一个事件类型绑定多个事件处理函数
=> 多个事件处理函数的时候,顺序绑定顺序执行
=> 至少两个参数
2-2. attachEvent()
=> IE 低版本使用
=> 语法: 元素.attachEvent('on事件类型', 事件处理函数)
=> 可以同时给一个事件类型绑定多个事件处理函数
=> 多个事件处理函数的时候,顺序绑定倒序执行
=> 只有两个参数
<div id="box"></div>
// 0. 获取元素
var div = document.querySelector('div')
// 2. 事件侦听器
// 2-1. addEventListener()
div.addEventListener('click', function(){
console.log('你好 世界')
})
div.addEventListener('click', function(){
console.log('hello world')
})
div.addEventListener('click', function(){
console.log('我被点击了')
})
<div id="box"></div>
// 0. 获取元素
var div = document.getElementById('box')
// 2. 事件侦听器
// 2-2. attachEvent()
div.attachEvent('onclick', function(){
console.log('你好 世界')
})
div.attachEvent('onclick', function(){
console.log('hello world')
})
div.attachEvent('onclick', function(){
console.log('我被点击了')
})
事件的解绑
复杂数据类型的比较:
+ 复杂数据类型在比较的时候,是进行地址的比较
+ 复杂数据类型的变量存储的就是一个在 堆 里面的地址
// 0. 复杂数据类型的比较
var obj = { name: 'Jack' }
var obj2 = { name: 'Jack' }
// 当 obj 存储的地址 和 obj2 存储的地址一模一样的时候才会得到 true
console.log(obj == obj2) // false
// 把 obj 存储的地址赋值给了 obj 一份
var obj3 = obj
console.log(obj3 == obj) // true
解绑 dom0级 事件
1. 解绑 dom0级 事件
=> 因为是赋值的行为
=> 所以直接再次给他赋值为 null
=> 就把之前的事件处理函数取代了
<style>
div{
width: 200px;
height: 200px;
background-color: pink;
}
</style>
<button id="btn">解绑事件</button>
<div id="box"></div>
// 0. 获取元素
var btn = document.getElementById('btn')
var div = document.getElementById('box')
// 1. 绑定事件
div.onclick = function(){
console.log('hello world')
}
btn.onclick = function(){
// 要给 div 解绑 dom0级 事件
div.onclick = null
}
解绑 dom2级 事件
(以下这种方式解绑不了)
那该怎么解绑呢??
2. 解绑 dom2级 事件
2-1. removeEventListener('事件类型', 要解绑的事件处理函数)
=> 注意: 如果你想解绑事件,那么在你绑定事件的时候,一定要把函数单独书写,写成一个具名函数的形式,以函数名的形式绑定事件处理函数!!!
2-2. detachEvent('on事件类型', 要解绑的事件处理函数)
=> 注意: 如果你想解绑事件,那么在你绑定事件的时候,一定要把函数单独书写,写成一个具名函数的形式,以函数名的形式绑定事件处理函数!!!
// 0. 获取元素
var btn = document.getElementById('btn')
var div = document.getElementById('box')
// 标准浏览器
// 2-1. 提前准备好事件处理函数
function clickHandler(){
console.log('hello world')
}
// 2-2. 绑定事件
// 注意: 不加()
// clickHandler() 表示把函数执行掉
// clickHandler 表示一个函数的地址
div.addEventListener('click', clickHandler)
// 2-3. 解绑事件
btn.onclick = function(){
// 给 div 解绑 dom2级 事件
div.removeEventListener('click', clickHandler)
}
// 2. IE 低版本
// 提前准备好事件处理函数
function clickHandler(){
console.log('hello world')
}
// 绑定
div.attachEvent('onclick', clickHandler)
btn.onclick = function(){
// 给 div 解绑 dom2级 事件
div.detachEvent('onclick', clickHandler)
}
封装事件绑定和解绑
+ 为什么要封装?
=> 因为有兼容问题
=> 为了使用方便
+ 封装需要几个参数?
=> 三个
=> 事件源, 事件类型, 数件处理函数
手动抛出异常
throw new Error('错误信息')
+ 用代码的方式在控制台报错
+ 一旦代码执行, 会直接中断程序
开始封装
1. 参数验证
1-1. ele 必传, 如果没有传递, 直接报错
1-2. ele 需要是一个 元素节点
=> 节点类型, nodeType: 1
2. 兼容处理
2-1. if(){}else{}
function on(ele, type, handler){
if(!ele) throw new Error('请按照规则传递参数')
if(ele.nodeType !== 1) throw new Error('事件源有问题')
// 2. 兼容处理
// div.addEventListener()
// div.attachEvent()
// 只要 元素 身上有这个函数,就可以执行
// 没有这个函数就去换另一个函数试试
if(ele.addEventListener){
ele.addEventListener(type, handler)
}else if(ele.attachEvent){
ele.attachEvent('on' + type, handler)
}else{
// 对象操作语法 - 点语法
// ele.onclick = handler
// 对象操作语法 - 数组关联语法
// ele['onclick'] = handler
ele['on' + type] = handler
}
}
var div = document.getElementById('box')
// 绑定事件
on(div, 'click', function(){console.log('hello world')})
// 事件解绑封装
function off(ele, type, handler){
if(!ele) throw new Error('请按照规则传递参数')
if(ele.nodeType !== 1) throw new Error('事件源有问题')
// 处理解绑的兼容
if(ele.removeEventListener){
ele.removeEventListener(type, handler)
}else if(ele.detachEvent){
ele.detachEvent('on' + type, handler)
}else{
ele['on' + type] = null
}
}
var div = document.getElementById('box')
var btn = document.getElementById('btn')
function clickHandler(){console.log('hello world')}
// 绑定事件
on(div, 'click', clickHandler)
// 解绑事件
on(btn, 'click', function(){
off(div, 'click', clickHandler)
})