一, Dom事件的级别
- dom0
事件的书写方式
<div id="box">Dom0</div>
</head>
<body>
<script>
var dom0 = document.getElementById('box')
dom0.onclick = function() {
console.log('dom1');
}
</script>
2.dom2事件的书写方式
<div id="box">Dom2</div>
</head>
<body>
<script>
var dom2 = document.getElementById('box')
dom2.addEventListener('click', ()=>{
console.log('dom2');
})
</script>
3.dom3
主要是在事件类型上加了很多
<script>
var dom3 = document
dom3.addEventListener('keyup', ()=>{
console.log('dom3');
}, false)
</script>
dom1并没有对事件做修改
二 事件流
2.1 什么是事件流?
事件流描述的是页面中接受事件的顺序,分为三个阶段: 捕获阶段--> 目标阶段--> 冒泡阶段
例子:
比如做一个点击事件,如何做到点击左键,再传到页面上的.
捕获阶段: 从上往目标元素捕获 ---事件通过捕获到达目标元素
目标阶段
冒泡: 从目标元素往上冒泡----从目标元素上传到window
2.2 事件捕获的具体流程
捕获是从上到目标元素 (js怎么能拿到当前的html节点:document.documentElement)
window -> document --> html --> body --> 目标元素
<!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>
<div id="box">测试捕获的顺序</div>
</head>
<body>
<script>
var box = document.getElementById('box')
document.body.addEventListener('click', ()=> {
console.log('body');
}, true)
window.addEventListener('click', ()=> {
console.log('window');
}, true)
document.addEventListener('click', ()=> {
console.log('document');
}, true)
box.addEventListener('click', ()=> {
console.log('目标元素');
}, true)
document.documentElement.addEventListener('click', ()=> {
console.log('html');
}, true)
</script>
</body>
</html>
结果
后面的传参数, false表示捕获, true是冒泡阶段,如果要测试冒泡,直接把顺序换过来.默认是冒泡。
三, event 对象的常见应用
3.1 e.preventDefault() --阻止系统默认行为
<a href="https://www.baidu.com" id="box">点我</a>
</head>
<body>
<script>
// 阻止系统默认行为
var box = document.getElementById('box')
box.addEventListener('click', (e)=> {
e.preventDefault()
})
</script>
</body>
3.2 e.stopPropagation() ---阻止冒泡
<div id="father">father
<div id="son">son</div>
</div>
</head>
<body>
<script>
var father = document.getElementById('father')
var son = document.getElementById('son')
father.addEventListener('click', ()=> {
console.log(1111);
})
son.addEventListener('click', (e)=> {
console.log(2222);
//加上之后不会冒泡到父元素了
e.stopPropagation()
})
</script>
3.event.stopImmediatePropagation() --- 多个类似事件绑定在同一个元素,阻止事件冒泡,也阻止后面的事件的执行
<!DOCTYPE html>
<html>
<head>
<style>
p { height: 30px; 150px; background-color: #ccf; }
div {height: 30px; 150px; background-color: #cfc; }
</style>
</head>
<body>
<div>
<p>paragraph</p>
</div>
<script>
const p = document.querySelector('p')
p.addEventListener("click", (event) => {
console.log("我是p元素上被绑定的第一个监听函数");
}, false);
p.addEventListener("click", (event) => {
console.log("我是p元素上被绑定的第二个监听函数");
event.stopImmediatePropagation();
// 执行stopImmediatePropagation方法,阻止click事件冒泡,并且阻止p元素上绑定的其他click事件的事件监听函数的执行.
}, false);
document.querySelector("div").addEventListener("click", (event) => {
console.log("我是div元素,我是p元素的上层元素");
// p元素的click事件没有向上冒泡,该函数不会被执行
}, false);
p.addEventListener("click",(event) => {
console.log("我是p元素上被绑定的第三个监听函数");
// 该监听函数排在上个函数后面,该函数不会被执行
}, false);
</script>
</body>
</html>
- e.target---触发事件的元素
e.currentTarget --- 捕获的元素
也可以说 e.target始终指向即当前点击的目标元素,e.currentTarget在事件委托中,如果监听元素不是目标元素,则指向监听元素
e.currentTarget指向的是addEventListener 监听的那个元素, e.target是指向的目标元素,可以查看事件委托---https://www.cnblogs.com/antyhouse/p/12298932.html
<div id="father">
<div>1</div>
<div id="second">2</div>
<div>3</div>
</div>
</head>
<body>
<script>
var box = document.getElementById('father')
box.addEventListener('click', (e)=> {
console.log('e.target',e.target);
console.log('e.currentTarget',e.currentTarget);
})
// event.currentTarget- 监听事件绑定的元素
// event.target- 触发事件的元素。事件可能冒泡到父元素,随意触发事件的可能是父元素。
</script>
</body>
四, 自定义事件
<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>
<div id="box">我就想自定义一个事件</div>
</head>
<body>
<script>
var custom = document.getElementById('box')
var newEve = new Event('newEveName')
custom.addEventListener('newEveName', ()=> {
console.log('do somthing');
})
custom.dispatchEvent(newEve)
</script>
</body>
</html>
以及
// 创建一个支持冒泡且不能被取消的look事件
var ev = new Event("look", {"bubbles":true, "cancelable":false});
document.dispatchEvent(ev);
// 事件可以在任何元素触发,不仅仅是document
myDiv.dispatchEvent(ev);