js事件的对象属性和方法。事件冒泡,捕获及委托。

6 篇文章 0 订阅
1 篇文章 0 订阅

一、事件的Event对象和属性

首先来看一段代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>event_bubble</title>
</head>
    <style>
        
    </style>
<body>
 	<div id="grand" class="box">
        <div id="far" class="box">
            <div id="son" class="box">
                <button id="butn" class="butn">click</button>
            </div>
        </div>
    </div>

    <script>
        document.getElementById("butn").onclick = function(){
        	console.log(event)
        }
    </script>
</body>

</html>

打印的内容如下图:
在这里插入图片描述
其中的一些属性:

view: 只读,对象,通常为发生事件的window对象;

type: 只读,字符串,发生事件类型:(图中为:click);

eventPhase: 只读,数字,事件流经历的阶段(1、捕获;2、目标;3、冒泡);

target: 只读,对象,派发事件的目标对象;

currentTarget: 只读,对象,当前在调用监听器的对象,就是当前 addEventListener 绑定的对象;

button: 只读,数字,被按下的鼠标键整数
		(1、鼠标左键;2、鼠标右键;3、鼠标左右同时;4、鼠标中键)
		(firefox 中:0、左键; 1、中间;2、右键)

cancelBubble: 布尔值,可以阻止事件冒泡,相当于 preventBubble();

returnValue: 布尔值,是否阻止浏览器默认事件动作,相当于 e.preventDefault();

screenX,screenY: 鼠标指针事件发生时相对于显示器左上角的位置;

cancelLable: 只读,布尔值,处理事件的默认行为是否可以阻止;
					若值为 true ,则 event 的preventDefalut 方法可以使用,
					若为 false,则不可用;
		
bubbles: 可读,布尔值,事件是否开启了冒泡;

preventDefault():  阻止浏览器的默认行为,IE中可以 return false 方法类似;

stopPropagation(): 停止当前事件流传播,但不会停止当前处理的对象;

preventBubble():  阻止冒泡,不建议使用,用stopPropagation()代替;

preventCapture:  阻止捕获,不建议使用,用stopPropagation()代替;

二、事件冒泡

js的事件传播中,当一个元素触发了事件后,事件会逐级向上传递给父辈,知道 document 为止。有的浏览器可能会到 window 为止,就像气泡向上冒出,这就是事件冒泡。eg:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>event_bubble</title>
</head>
    <style>
        .box{
            overflow: hidden;
            padding: 20px;
            border: 1px solid #333333;
        }
    </style>
<body>

    <div id="grand" class="box">
        <div id="far" class="box">
            <div id="son" class="box">
                <button id="butn" class="butn">click</button>
            </div>
        </div>
    </div>

    <script>
    	document.getElementsByTagName("body")[0].onclick = function(){
            console.log("body");
        }
        document.getElementById("grand").onclick = function(){
            console.log("grand");
        }
        document.getElementById("far").onclick = function(){
            console.log("far");
        }
        document.getElementById("son").onclick = function(){
            console.log("son");
        }
        document.getElementById("butn").onclick = function(){
        	console.log(event)
            console.log("butn");
        }
    </script>
</body>

</html>

在这里插入图片描述
如图:点击 按钮后:同时触发了,butn,son,far,grand,body,此类型成为事件冒泡。

所以开发中为了避免此类情况,需要阻止事件冒泡;

1、 使用标准的 w3c 的方式,e.stopPropagation(); 这里的stopPropagation的标准的事件对象的一个方法调用即可。
2、非标准的IE方式;window.event,cancelBubble = true; 这里的cancelBubble 是 IE 事件对象的属性,设为 true 即可。

document.getElementById("butn").onclick = function(){
	stopBubble();
}
var stopBubble = function(e) {
	// 如果提供了事件对象,则这是一个非IE浏览器
	if( e && e.stopPropagation){
		// 支持 w3c 的 stopPropagation();  方法
		e.stopPropagation();
	}else {
		// 否则使用 IE 的方式来获取取消事件 冒泡 
		window.event.cancelBubble = true;
	}
}

3、在 vue 开发中,methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。所以 vue 为 v-on 提供了事件修饰符;在标签上写.stop

<p>
	<button @click.stop="handleClick"></button>
	<button v-on:click.stop="handleClick"></button>
</p>

三、事件捕获

与事件冒泡相反,它从顶层元素开始,直到事件触发底层元素。

如何触发事件捕获

	target.addEventListener(type, function(){}, boolean);
// target为 document 元素
// type 为事件类型
// boolean 布尔值, true 时为事件捕获 false 为事件冒泡
// eg:
document.getElementById("grand").addEventListener("onclick", function(){
            console.log("grand");
        }, true ); // 为id为 grand 的元素添加事件捕获

三、事件委托

what: 事件委托就是利用事件冒泡原理,指定一个事件程序来管理一类的所有事件。

why: 一般来说。dom 元素需要有事件处理时,给元素添加事件和程序即可,但是当添加事件的 dom 元素数量过多时就会影响页面的整体性能,比如:有 100 个列表中的 button 需要添加 click 点击事件,我们会利用 for 循环的方法遍历所有相应的 button 元素,然后添加 click 点击事件。这样会需要不断的与 dom 节点进行交互,访问的 dom 越多,引起浏览器重绘和重排的次数就会变多,从而延长整个页面的交互处理时间。
所以需要事件委托把所有的操作放在一个元素或者程序中,只进行一次 dom 操作,可以大大的减少了 dom 操作的次数,提高性能。

how: 利用冒泡原理,将所有子元素的事件触发,写在其父级元素上。委托代为执行事件。

eg:

<ul id="list">
	<li class="li"><button>1</button></li>
	<li class="li"><button>2</button></li>
	<li class="li"><button>3</button></li>
	<!-- 中间省略 -->
	<li class="li"><button>9</button></li>
	<li class="li"><button>10</button></li>
</ul>

要点击 button 时,通常写的代码:

var btns = document.getElementsByTagName("button");

for(let i = 0; i < btns.length; i++){
	btns[i].onclick = function () {
		alert(btns[i].innerHtml);
	}
}

获取到 button ,点击 button ,要多次寻找目标的 button 的位置,才能执行最后的操作。利用事件委托把点击事件的触发写在父级元素 ul 上,那么所有的 li 和 button 都会被触发,Event 对象提供了一个属性到 target ,可以返回事件的目标节点, target 可以表示当前的事件操作的 dom元素,但不是真的 dom ,具有兼容性,标准浏览器用 ev.target, ie 用event.srcElement 可获取当前目标节点的位置。

document.getElementById("list").onclick = function() {
	var ev = event || window.event;
	var target = ev.target || ev.srcElement;
	if(target.nodeName.toLowerCase() == "BUTTON"){
		alert(target.innerHtml);
	}
}

可以委托的事件:click, mousedown , mouseup , keydown , keyup , keypress;
mouseenter , mouseleave , focus , blur 等不适合事件委托

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值