28 【事件传播】

本文详细介绍了JavaScript中的事件传播机制,包括事件冒泡、阻止冒泡和阻止默认事件。重点讲解了事件委托的概念,如何利用事件冒泡来提高性能,以及在事件委托中e.target和e.currentTarget的区别。此外,还探讨了事件流的三个阶段和addEventListener方法的第三个参数对事件处理的影响。
摘要由CSDN通过智能技术生成

事件传播

1.事件冒泡

事件冒泡概念:
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
事件冒泡是默认存在的

鼠标经过事件:
mouseovermouseout 会有冒泡效果
mouseentermouseleave 没有冒泡效果(推荐)

		<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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DSelegent

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值