一、 注册事件
给元素添加事件,称为 注册事件 或者 绑定事件
注册事件有两种方式: 传统方式 和 方法监听注册方式
1.1 传统注册方式
传统注册方式:
-
利用 on 开头的事件onclick
-
<button onclick= "alert(hi~")”>
-
btn.onclick=function(){}
-
特点: 注册事件的
唯一性 -
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
<html>
<body>
<button>传参注册事件</button>
<button>方法监听注册事件</button>
<script>
var btns = document.querySelectorAll("button")
btns[1].addEventListener(
'click',
function(){
alert("hello ")
})
btns[1].addEventListener(
'click',
function(){
alert("world!")
})
</script>
</body>
</html>
方法监听注册方式
- w3c标准 推荐方式
- addEventListener()它是一个方法
- IE9 之前的 IE 不支持此方法,可使用 attachEvent() 代替
- 特点:同一个元素同一个事件可以注册多个监听器
- 按注册顺序依况执行
1.2 addEventListener 事件监听方式
eventTarget .addEventListener(type,listenerl,usecapture])
eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
该方法接收三个参数:
- type: 事件类型字符串,比如click、mouseover,注意这里不要带on
- listener: 事件处理函数,事件发生时,会调用该监听函数
- useCapture: 可选参数,是一个布尔值,默认是false。
<html>
<body>
<button>传参注册事件</button>
<button>方法监听注册事件</button>
<script>
var btns = document.querySelectorAll("button")
// 事件监听方式
btns[1].addEventListener(
'click',
function(){
alert("hello ")
})
btns[1].addEventListener(
'click',
function(){
alert("world!")
})
</script>
</body>
</html>
1.3 attachEvent 注册事件
eventTarget.attachEvent(eventNamewithon, callback)
eventTarget.attachEvent() 方法将指定的监听器注册到eventrarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行。
该方法接收两个参数:
-
eventNameWithOn: 事件类型字符串,比如onclick、onmouseover,这里要带on
-
callback:事件处理函数,当目标触发事件时回调函数被调用
<html>
<body>
<button>传参注册事件</button>
<button>方法监听注册事件</button>
<button>attachEvent 监听事件</button>
<script>
var btns = document.querySelectorAll("button")
btns[2].attachEvent('onClick',function(){
alert("attachEvent")
})
</script>
</body>
</html>
二、 删除事件
<html>
<body>
<button>添加点击事件并触发</button>
<button>传统方式删除点击事件</button>
<button>方法监听注册方式删除点击事件</button>
<script>
var btns = document.querySelectorAll("button")
// 添加点击使劲啊
btns[0].onclick = fn
function fn(){
alert('hello')
}
// 1. 传统方式删除事件
btns[1].onclick = null
// 2. 方法监听注册方式
btns[2].removeEventListener('click',fn)
</script>
</body>
</html>
三、Dom 事件流
事件流描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM 事件流.
比如我们给一个div注册了点击事件:
DOM 事件流分为3个阶段:
1.捕获阶段
2.当前目标阶段
3.冒泡阶段
事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到DOM 最顶层节点的过程。
事件捕获: 网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。
注意
Js 代码中只能执行 捕获 或者 冒泡 其中的一个阶段。
onclick 和 attachEvent 只能得到冒泡阶段.
addEventListener(type,listener[,usecapture]) 第三个参数如果是 true, 表示在事件 捕获 阶段调用事件处理程序;如果是 false(不写默认就是fa1se),表示在事件 冒泡 阶段调用事件处理程序。
实际开发中我们很少使用事件捕获,我们更关注事件冒泡.
有些事件是没有冒泡的, 比如 onblur、onfocus、onmouseenter、onmouseleave
<html>
<body>
<div class="father" style="width: 400px;height: 400px;background-color: yellowgreen;">
<div class="son" style="width: 200px;height: 200px;background-color: rebeccapurple;">son</div>
</div>
<script>
// dom 事件流 三个阶段
// 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
// 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。
// 3. 捕获阶段 如果addEventListener 第三个参数是 true
// 那么则处于捕获阶段 document->html->body ->father -> son
var son = document.querySelector('.son')
son.addEventListener('click',function(){
alert('son')
},true)
var father = document.querySelector('.father')
father.addEventListener('click',function(){
alert('father')
},true)
// 4.冒泡阶段 如果addEventListener第三个参数是 false 或者 省略
// 那么则处于冒泡阶段son ->father ->body>html->document
var son = document.querySelector('.son')
son.addEventListener('click',function(){
alert('son')
})
var father = document.querySelector('.father')
father.addEventListener('click',function(){
alert('father')
},false)
</script>
</body>
</html>
四、事件对象
4.1 相关概念
-
event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看
-
事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
-
事件对象是我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键
-
这个事件对象我们可以自己命名比如event、evt、e
-
事件对象也有兼容性问题, ie678 通过 window.event 兼容性的写法
e = e| window.event;
<html>
<body>
<div>btn</div>
<script>
var div = document.querySelector('div')
div.addEventListener('click',(e)=>{
// 解决兼容性问腿
e = e || window.event
console.log(e)
})
</script>
</body>
</html>
4.2 常见属性和方法
<html>
<body>
<div class="father">
<a href="www.baidu.com" class='son'>link</a>
</div>
<script>
var son = document.querySelector('.son')
son.addEventListener('click',(e)=>{
// target 返回触发事件的对象(元素)
console.log(e.target)
// this 返回的是绑定对事件的对象(元素)
console.log(this)
// 返回事件类型
console.log(e.type)
// 阻止默认行为: 普通浏览器 e.preventDefault();方法
e.preventDefault();
// 阻止默认行为:低版本浏览器ie678 returnValue 属性
//e.returnValue;
// 阻止默认行为:我们可以利用return false 也能阻止默认行为 没有兼容性问题
// 但是 return 之后的代码就不执行了
// return false;
})
</script>
</body>
</html>
五、阻止事件冒泡
<html>
<body>
<div class="father" style="width: 200px;height: 200px;background-color: antiquewhite;">
<button class='son'>btn</button>
</div>
<script>
var son = document.querySelector('.son')
son.addEventListener('click',(e)=>{
console.log('son')
// 1. 取消冒泡
e.stopPropagation()
// 2. 非标准取消冒泡
// e.cancelable = true
// 3. 解决兼容性问题
if(e && e.stopPropagation){
e.stopPropagation()
}else{
window.event.cancelable = true
}
})
var father = document.querySelector('.father')
father.addEventListener('click',(e)=>{
console.log('father')
})
</script>
</body>
</html>
六、事件委托(代理、委派)
事件委托也称为事件代理,在jQuery里面称为事件委派。
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
我们只操作了一次 DOM,提高了程序的性能。
<html>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var ul = document.querySelector('ul')
ul.addEventListener('click',function(e){
console.log('click')
// e.target 可以获取点击的对象
e.target.style.color = 'red'
})
</script>
</body>
</html>
七、 常见的鼠标事件
7.1 禁止右击和选中
禁止鼠标右键菜单
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
禁止鼠标选中(selectstart 开始选中)
<html>
<body>
<div>我是一段不愿 复制 的文字</div>
<div>我是一段不愿 选中 的文字</div>
<script>
var divs = document.querySelectorAll('div')
divs[0].addEventListener('contextmenu',function(e){
e.preventDefault()
})
divs[1].addEventListener('selectstart',function(e){
e.preventDefault()
})
</script>
</body>
</html>
7.2 鼠标事件对象
event 对象代表事件的状态,跟事件相关的一系列信息的集合。
现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent。
<html>
<body>
<div style="
margin-left: 2000PX;
margin-top: 2000px;
width: 200px;
height: 200px;
background-color: antiquewhite;"
></div>
<script>
var div = document.querySelector('div')
div.addEventListener('click',function(e){
// client 返回的永远是可视窗口的坐标
console.log('x: ' + e.clientX)
console.log('y: ' + e.clientY)
// page 返回的永远是总体页面的坐标
console.log('x: ' + e.pageX)
console.log('y: ' + e.pageY)
})
</script>
</body>
</html>
八、键盘事件
8.1 常用事件
事件除了使用鼠标触发,还可以使用键盘触发。
<html>
<body>
<script>
// 常用的键盘事件
// 1. keyup 按键弹起时触发
// document.onkeyup = function(){
// console.log('up')
// }
document.addEventListener("keyup",function(){
console.log('up')
})
// 2. keydown 按下按键时触发
document.addEventListener("keydown",function(){
console.log('down')
})
// 3. keypress 按下按键时触发, 不能识别功能键
document.addEventListener("keypress",function(){
console.log('press')
})
// 4. 三个事件的执行顺序: keydown -> keypress -> keyup
</script>
</body>
</html>
8.2 键盘事件对象
<html>
<body>
<script>
// 1. keyup 和 keydown 不区分字母大小写,A 和 a 得到的都是 65
document.addEventListener("keyup",function(e){
console.log(e.keyCode)
})
// 2. keypress 区分字母大小写
document.addEventListener("keypress",function(e){
console.log(e.keyCode)
})
</script>
</body>
</html>