事件传播
1.事件冒泡
事件冒泡概念:
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
事件冒泡是默认存在的
鼠标经过事件:
mouseover
和 mouseout
会有冒泡效果
mouseenter
和 mouseleave
没有冒泡效果(推荐)
<style type="text/css">
#box1{
width: 200px;
height: 200px;
background-color: yellowgreen;
}
#s1{
background-color: yellow;
}
</style>
<script type="text/javascript">
window.onload = function(){
/*
* 事件的冒泡(Bubble)
* - 所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
* - 在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡
*
*/
//为s1绑定一个单击响应函数
var s1 = document.getElementById("s1");
s1.onclick = function(event){
event = event || window.event;
alert("我是span的单击响应函数");
//取消冒泡
//可以将事件对象的cancelBubble设置为true,即可取消冒泡,这样祖先元素相同事件就不会被触发
event.cancelBubble = true;
};
//为box1绑定一个单击响应函数
var box1 = document.getElementById("box1");
box1.onclick = function(event){
event = event || window.event;
alert("我是div的单击响应函数");
/*因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素。若想把事件就限制在当前元素内,就需要阻止事件流动阻止事件流动需要拿到事件对象。
此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效*/
// e.stopPropagation()
};
//为body绑定一个单击响应函数
document.body.onclick = function(){
alert("我是body的单击响应函数");
};
};
</script>
<body>
<div id="box1">
我是box1
<span id="s1">我是span</span>
</div>
2.阻止冒泡
阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。
stopPropagation
方法阻止事件在 DOM 中继续传播,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上其他的事件监听函数。
function stopEvent(e) {
e.stopPropagation();
}
el.addEventListener('click', stopEvent, false);
上面代码中,click
事件将不会进一步冒泡到el
节点的父节点。
<body>
<h3>阻止冒泡</h3>
<p>阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。</p>
<div class="outer">
<div class="inner">
<div class="child"></div>
</div>
</div>
<script>
// 获取嵌套的3个节点
const outer = document.querySelector('.outer')
const inner = document.querySelector('.inner')
const child = document.querySelector('.child')
// 外层的盒子
outer.addEventListener('click', function () {
console.log('outer...')
})
// 中间的盒子 inner.addEventListener('click', function (ev) {
console.log('inner...')
// 阻止事件冒泡
ev.stopPropagation()
})
// 内层的盒子
child.addEventListener('click', function (ev) {
console.log('child...')
// 借助事件对象,阻止事件向上冒泡
ev.stopPropagation()
})
</script>
</body>
结论:事件对象中的 e.stopPropagation
方法,专门用来阻止事件冒泡。
3.阻止默认事件
e.preventDefault()
方法用来阻止事件产生的 “默认动作”。
一些特殊的业务需求,需要阻止事件的 “默认动作”。
【小案例1】
制作一个文本框,只能让用户在其中输入小写字母和数字,其他字符输入没有效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>
只能输入小写字母和数字:
<input type="text" id="field">
</p>
<script>
var oField = document.getElementById('field');
oField.onkeypress = function (e) {
console.log(e.charCode);
// 根据用户输入的字符的字符码(e.charCode)
// 数字 0~9,字符码 48~57
// 小写字母 a~z,字符码 97~122
if (!(e.charCode >= 48 && e.charCode <= 57 || e.charCode >= 97 && e.charCode <= 122)) {
// 阻止浏览器的默认行为
e.preventDefault();
}
};
</script>
</body>
</html>
【小案例2】
制作鼠标滚轮事件:当鼠标在盒子中向下滚动时,数字加 1;反之,数字减 1。
鼠标滚轮事件是 onwheel
,它的事件对象 e 提供 deltaY
属性表示鼠标滚动方向,向下滚动是返回正值,向上滚动时返回负值。
- 没有阻止事件的 “默认动作” 时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=d