事件绑定
种类
DOM0级事件 语法: 标签对象.事件类型 = 函数
a同一个节点同一事件只能设置一次,多次着后者覆盖前者
b无兼容问题
c事件流不支持
DOM1级事件 没有**
DOM2级事件
a同一个节点同一事件可以绑定多个函数,按照绑定顺序执行
b有兼容问题
c支持处理事件流
DOM3级事件 (语法不变只是增加了事件类型)
DOM3级事件在DOM2级事件的基础上【添加了更多的事件类型】,全部类型如下:
UI事件,当用户与页面上的元素交互时触发,如:load、scroll
焦点事件,当元素获得或失去焦点时触发,如:blur、focus
鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
等等
DOM0级事件
语法
设置:标签对象.事件类型 = function() { // 代码 }
取消:标签对象.事件类型 = null
<标签名 属性名n=“属性值n” οnclick=“函数名()” >内容</标签名> setTimeout(“函数名()”, 毫秒)
练习:添加DOM0级事件 和 取消DOM0级事件**
<div style="width:100px;height:100px;background:red"></div>
<button id="btn1">设置</button>
<button id="btn2">取消</button>
<script>
// 1. 搞一个按钮 点击给div设置点击事件
var btn1 = document.querySelector('#btn1') //获取按钮1
btn1.onclick = function() { //给按钮1绑定点击事件
var div = document.querySelector('div') //获取div
div.onclick = function() { //当按钮被点击就给div绑定点击事件
alert("神龙教主") //当div上的点击事件被触发就弹出提示框
}
}
// 2. 搞一个按钮 取消div事件
var btn2 = document.querySelector("#btn2") //获取按钮2
btn2.onclick = function() { //给按钮2绑定点击事件
var div = document.querySelector('div') //获取div
div.onclick = null //当按钮被点击就给div绑定的点击事件设为null,也就取消了div上的点击事件
}
</script>
DOM2级事件
语法
非主流ie6\7\8
设置:标签对象.attachEvent(事件类型, 处理函数)
取消:标签对象.detachEvent(事件类型, 处理函数)
主流
设置:标签对象.addEventListener(事件类型, 处理函数 [, 事件流])
取消:标签对象.removeEventListener(事件类型, 处理函数 [, 事件流])
其 他:事件流默认冒泡型-false,捕获型-true
留心1:DOM2主流事件类型不需要加on
留心2:DOM2只要你想取消,第二个参数就必须写变量名
练习:添加DOM2级事件 和 取消DOM2级事件
<div style="width:100px;height:100px;background:red">DOM2</div>
<button id="btn1">设置</button>
<button id="btn2">取消</button>
<script>
// 赋值式函数
var fn = function() {
alert('神龙教主 洪福齐天')
}
// 1. 搞一个按钮 点击给div设置点击事件 弹出 神龙教主
var btn1 = document.querySelector('#btn1')
btn1.onclick = function() {
// 给div绑定事件 切记切记切记 绑定了就会一直生效 除非1刷新网页,2主动取消
var divObj = document.querySelector('div')
divObj.addEventListener("click", fn)
}
// 2. 搞一个按钮 取消div事件
var btn2 = document.querySelector("#btn2")
btn2.onclick = function() {
// 给div移除事件
var divObj = document.querySelector('div')
// console.log(divObj) // <div style="width:100px;height:100px;background:red">DOM2</div>
divObj.removeEventListener('click', fn)
}
</script>
同类型的事件(了解)
-DOM0 同标签、同类型 覆盖
<div style="width:100px;height:100px;background:red;"></div>
<script>
// 1. 获取
var div = document.querySelector('div')
// 2. 设置
div.onclick = function() {
console.log(1)
}
div.onclick = function() {
console.log(2)
}
div.onclick = function() {
console.log(3)
}
// 设置了3个 但是最终只输出最后一个 覆盖
</script>
- DOM2 同标签、同类型 累计
- 脚下留心:第二个值是函数 在同一个盒子会覆盖,不同盒子不会覆盖
<div style="width:100px;height:100px;background:red;"></div>
<script>
// 1. 获取
var div = document.querySelector('div')
// 2. 设置
// div.addEventListener('click', function() {
// console.log(1)
// })
// div.addEventListener('click', function() {
// console.log(1)
// })
// div.addEventListener('click', function() {
// console.log(1)
// })
// 明确:上述代码累计 输出111
// 留心:如果你要取消 就不能直接写function 而是要复制给变量
// 举例:下述代码就不能取消 因为没有复制给变量
// div.addEventListener('click', function() {
// console.log(4)
// })
// 解决:
// var fn = function() {
// console.log(4)
// }
// div.addEventListener('click', fn)
// 留心:不覆盖的前提 第二个参数也就是处理函数 不能指向同一个空间
// 思考:下述代码 输出 3个1 还是 仅1个
// 回答:仅1个
// 因为:最终只绑定成功1个
var fn = function() {
console.log(1)
}
div.addEventListener('click', fn)
div.addEventListener('click', fn)
div.addEventListener('click', fn) // 因为同一个盒子 所以覆盖了
</script>
DOM2级事件好处
- 设置多个同类型事件
- 可以操作事件流
事件流(冒泡型,捕获型)
简介
- 概念:多个标签彼此嵌套,并且都设置了事件
- 特性:操作一个,所有都触发(隔山打牛)
练习
<style>
.div1 {width: 300px;height: 300px;background: red;}
.div2 {width: 200px;height: 200px;background: blue;}
.div3 {width: 100px;height: 100px;background: green;}
</style>
<div class="div1">
<div class="div2">
<div class="div3"></div>
</div>
</div>
<script>
// 1. 获取标签
var div1Obj = document.querySelector('.div1')
var div2Obj = document.querySelector('.div2')
var div3Obj = document.querySelector('.div3')
// 2. 设置事件
div1Obj.onclick = function() {
console.log('this is div1 yeye')
}
div2Obj.onclick = function() {
console.log('this is div2 father')
}
div3Obj.onclick = function() {
console.log('this is div3 son')
}
</script>
事件流种类
- 解释
冒泡型(从里向外)
捕获型(从外向里)
- 说明
DOM0级事件都是冒泡型(无法概念
DOM2级事件默认冒泡型false、捕获型true (注:IE低版本浏览器都是冒泡型)
- 验证
DOM1级就是冒泡型事件,无法改变
<style>
.div1 {width: 300px;height: 300px;background: red;}
.div2 {width: 200px;height: 200px;background: blue;}
.div3 {width: 100px;height: 100px;background: green;}
</style>
<div class="div1">
<div class="div2">
<div class="div3"></div>
</div>
</div>
<script>
// 1. 获取标签
var div1Obj = document.querySelector('.div1')
var div2Obj = document.querySelector('.div2')
var div3Obj = document.querySelector('.div3')
// 2. 设置事件
div1Obj.onclick = function() {
console.log('this is div1 yeye')
}
div2Obj.onclick = function() {
console.log('this is div2 father')
}
div3Obj.onclick = function() {
console.log('this is div3 son')
}
</script>
DOM2级事件IE9以下统一冒泡型事件,无法改变
DOM2级事件IE9及以上,默认冒泡事件;可通过更改第三个参数动态设置事件事件流:默认false表示冒泡型,true表示捕捉型
<style>
.div1 {width: 300px;height: 300px;background: red;}
.div2 {width: 200px;height: 200px;background: blue;}
.div3 {width: 100px;height: 100px;background: green;}
</style>
<div class="div1">
<div class="div2">
<div class="div3"></div>
</div>
</div>
<script>
// 1. 获取标签
var div1Obj = document.querySelector('.div1')
var div2Obj = document.querySelector('.div2')
var div3Obj = document.querySelector('.div3')
// 2. 设置事件
div1Obj.addEventListener('click', function(){
console.log('this is div1 yeye')
}, true)
div2Obj.addEventListener('click', function(){
console.log('this is div2 father')
}, true)
div3Obj.addEventListener('click', function(){
console.log('this is div3 son')
}, true)
</script>
小总结
事件流是什么:多个标签彼此嵌套,并且都设置事件
事件流特性:操作一个,全部触发
事件流种类:冒泡、捕获型(DOM2主流浏览器可以更改)
为什么要学习事件流:防止后期遇到bug怀疑人生
事件对象
概念
- 是什么:用来存放事件相关信息的对象
- 存了啥:很多比如你是按的键盘还是鼠标、事件源等
- 能干吗:
1 回车表单提交 登录注册输入账号密码之后回车提交
2 阻止浏览器默认动作 比如点击a标签、点击表单提交阻止不刷新等等
3 鼠标位置 比如放大镜、游戏
4 阻止事件流
语法
Ø 主流浏览器
通过 处理函数 的第一个形参(谁传递了实参,官方)
标签对象.事件类型 = function(e) { // e evt event
}
Ø ie6、7、8
标签对象.事件类型 = function() {
window.event // 打印事件对象信息
}
Ø 兼容
标签对象.事件类型 = function(e) {
var e = e || window.event
}
初体验
点击按钮,触发事件,打印查看事件对象信息
<button id="btn">点击触发事件</button>
<script>
// 1. 获取标签对象
var btnObj = document.querySelector('#btn')
// 2. 绑定事件
btnObj.addEventListener('click', function(e) {
var e = e || window.event
console.log(e)
})
</script>
作用1(回车表单提交!!!)
- 说明
我们的键盘上每一个按键都有一个自己独立的编码
我们就是靠这个编码来确定我们按下的是哪个按键的
我们通过 【事件对象.keyCode】 或者 【事件对象.which】 来获取
为什么要有两个呢,是因为 FireFox2.0 不支持 keycode 所以要用 which
举例:回车键 13
- 相关语法
document.keyup = function (e) {
// 事件对象的兼容写法
e = e || window.event
// 获取键盘码的兼容写法
var keyCode = e.keyCode || e.which
console.log(keyCode)
}
表单对象.submit() 用js提交表单(回车用 相当于你点击了表单提交按钮
表单对象.onsubmit = function() {} 监听表单是否提交
- 练习
<form action="">
<p>
用户名:
<input type="text" name="uname" id="">
</p>
<p>
密码:
<input type="text" name="pwd" id="">
</p>
<p>
<input type="submit" value="登录" id="">
</p>
</form>
<script>
// 1. 监控你回车了
// 2. 用js实现表单提交
// 1. 监控你回车了(给整个网页设置键盘按下事件 - 判断是哪个键
document.addEventListener('keydown', function(e) {
// console.log('你操作键盘了')
// 1.1 先获取事件对象
var e = e || window.event
// console.log(e)
// 1.2 在获取keyCode
var keyCode = e.keyCode || e.which
// 1.3 判断等于13
if (keyCode == 13) {
// console.log('监控按下回车,表单提交中...')
// 通过js语法 表单对象.submit()
// 作用:相当于你点击了提交按钮
var formObj = document.querySelector('form')
formObj.submit()
}
})
// 2. 用js实现表单提交
</script>
作用2(阻止浏览器默认动作!!!)
- 概念
起床,默认(睁眼
上厕所,默认(先脱裤子
计算机,a标签点击 默认跳转
计算机,表单提交 默认跳转处理
实战中:会经常需要组织默认动作
a 标签阻止目录就是交给js处理 比如弹框等
form 阻止默认提交 用js验证判断是否输入用户名或密码 没问题之后js自己提交
- 语法
DOM0 事件处理函数中 return false
DOM0/DOM2(推荐 事件处理函数中 e.preventDefault()
- 代码
<a href="http://baidu.com">百度</a>
<form action="">
<p>用户名: <input type="text" name="uname" id=""></p>
<p>密码:<input type="text" name="pwd" id=""></p>
<p><input type="submit" value="登录"></p>
</form>
<script>
// 2. 监控表单提交 阻止提交
// 获取form标签,增加表单提交事件
var formObj = document.querySelector('form')
formObj.onsubmit = function(e) {
// 在事件处理函数中阻止
// 阻止默认动作
var e = e || window.event
e.preventDefault()
console.log('表单提交了 我给你阻止')
}
// 1. 点击a标签阻止跳转
// 1.1 获取a
var a = document.querySelector('a')
// 1.2 点击事件
a.addEventListener('click', function(evt) {
// 1.3 阻止默认动作
// 获取事件对象
var e = evt || window.event
// 阻止
e.preventDefault()
})
</script>
作用3(事件对象中记录的鼠标位置!!)
语法 | 解释 |
---|---|
evt.screenX | 相对于屏幕的左上角为原点 |
evt.screenY | |
evt.clientX | 相对于浏览器的客户端左上角为原点(不计算滚动条位置) |
evt.clientY | |
evt.pageX | 相对于浏览器的客户端左上角为原点(计算滚动条的位置) |
evt.pageY | |
evt.offsetX | 以自己的左上角为原点 |
evt.offsetY |
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点击添加随机大小红方块</title>
<style>
* {padding:0px;margin: 0px;}
body {background: black;}
</style>
</head>
<body>
<script>
// 1. 给【网页】绑定【点击事件】
document.addEventListener('click', function(e) {
// 2. 事件处理函数中 -> 创建img标签 页面显示
var divobj = document.createElement("div")
var w = Math.floor(Math.random() * (80-30+1)+30)
var h = Math.floor(Math.random() * (80-30+1)+30)
divobj.style.width = w + 'px'
divobj.style.height = h + 'px'
divobj.style.backgroundColor="red"
// 定位
divobj.style.position = 'absolute'
var e = e || window.event
divobj.style.top = e.clientY - h/2 + 'px'
divobj.style.left = e.clientX - w/2 + 'px'
// 追加:父.appendChild(子)
document.body.appendChild(divobj)
})
</script>
</body>
</html>
作用4(阻止事件流!!)
- ie6、7、8:event.cancelBubble=true;
- 主流浏览器:evt.stopPropagation();
<style>
.div1 {width: 300px;height: 300px;background: red;}
.div2 {width: 200px;height: 200px;background: green;}
.div3 {width: 100px;height: 100px;background: blue;}
</style>
<div class="div1">
<div class="div2">
<div class="div3"></div>
</div>
</div>
<script>
var div1 = document.querySelector('.div1')
var div2 = document.querySelector('.div2')
var div3 = document.querySelector('.div3')
div1.addEventListener('click', function(e) {
console.log('this is div1')
var e = e || window.event
e.stopPropagation()
})
div2.addEventListener('click', function() {
console.log('this is div2')
var e = e || window.event
e.stopPropagation()
})
div3.addEventListener('click', function() {
console.log('this is div3')
var e = e || window.event
e.stopPropagation()
})
</script>
小总结
事件对象是什么:用来存放事件相关信息
事件对象存了啥:target事件源、鼠标位置、键盘按键等等
固定语法:var e = e || window.event (切记 e 是事件处理函数的第一个形参)
事件对象能干吗:
- 表单回车提交
- 阻止浏览器默认动作
- 鼠标位置
- 阻止事件流