10、事件流和事件委托

事件流和事件委托

  • 事件流
  • 事件委托

一、事件流

1.1、说明

​ 事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候, 并不是只有当前被点击的元素会触发事件 , 而是所有元素都会触发事件。而如果我们想要只触发其中一个事件时,此时就需要取消冒泡或捕获。浏览器默认都是冒泡类型
​ 由W3C规定的DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡

1.2、捕捉

​ 当你鼠标点击或触发一个dom事件时,浏览器会从根节点(Node)开始由外到内依次捕获注册了该dom事件的元素,然后再通过冒泡原理由内向外依次执行事件触发函数。

<body>
    <div onclick="second"><!--从外向里捕获-->
        <div onclick="first">重合起来就对了</div><!--从里向外冒泡-->
    </div>
    <script>
    	function second(){
			console.log("外面的盒子");  
        }
        function first() {
            console.log("里面的盒子");
        }
    </script>
</body>
<!--
------------Console-----------
里面的盒子
外面的盒子
-->

1.3、冒泡

​ 当你点击一个子元素时,所有注册了“onclick”事件函数的父元素,都会从里向外逐个触发该事件。

<div id="div1" onclick="open1()">
	<input type="button" value="确定" onclick="close1()">
</div>

<script>
    function open1() {
        alert("盒子被点击了");//后弹出
    }
    function close1() {
        alert("按钮被点击了");//先弹出
    }
</script>

二、事件委托

2.1、为什么要用事件委托?

从性能上:在JavaScript中,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间(性能)。——>减少与dom的交互操作。
从内存上:每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大。——>减少函数数量

2.2、委托的原理

​ 事件委托是利用事件的冒泡原理来实现的。

2.3、委托的实现

  • 不通过委托,如果我们要给div中的p注册"onclick"事件怎么做?
<div id="div1">
	<p>1111111</p>
	<p>2222222</p>
	<p>3333333</p>
</div>

<script>
    let pList = document.getElementsByTagName("p");
    for (let i=0;i<pList.length;i++){
        pList[i].onclick=function () {
            console.log(i);//onclick事件主体
        }
    }
</script>

10000个p定义10000个onclick?呵呵~

  • 同样的需求,通过委托来实现
<div id="div1">
	<p>1111111</p>
	<p>2222222</p>
	<p>3333333</p>
</div>

<script>
    document.getElementById("div1").onclick=function (event) {
    	let target = event.target;//获取事件触发事件的节点对象
        console.log();//onclick事件主体
    };
</script>

内存和性能得到了很大的提升

  • 如果每个子节点的触发事件都要实现不同的效果怎么办?
<div id="div1">
	<p id="add">1111111</p>
	<p id="remove">2222222</p>
	<p id="write">3333333</p>
</div>

<script>
    document.getElementById("div1").onclick=function (event) {
    	let target = event.target;//获取事件触发事件的节点对象
    	switch(target.id){
            case "add":
                console.log("add");
                break;
            case "remove":
                console.log("remove");
                break;
            case "write":
                console.log("write");
                break;
        }
    };
</script>

其实是一样的,

  • 那如果新增一个节点,新增的节点会有事件吗?
<div id="div1">
	<p id="add">1111111</p>
	<p id="remove">2222222</p>
	<p id="write">3333333</p>
</div>
<input type="button" value="添加" id="input1">

<script>
    document.getElementById("div1").onclick=function (event) {
    	let target = event.target;//获取事件触发事件的节点对象
    	switch(target.id){
            case "add":
                console.log("add");
                break;
            case "remove":
                console.log("remove");
                break;
            case "write":
                console.log("write");
                break;
        }
    };
	document.getElementId("input1").onclick=function () {
        let newP = document.createElement("p");
        newP.innerText = "新增";
        $("div1").appendChild(newP);
    };
</script>

还是一样的,新增节点也是有事件的,因为target是动态的?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值