事件冒泡,委托机制和浏览器的默认行为

it2024-09-26  51

事件冒泡,事件委托机制

一、事件冒泡


概念:当一个元素触发了事件的时候,会依次向上触发所有元素的相同事件,即依次向父级传递,一直到window。

举个例子

var div1 = document.getElementById("div1"); var div2 = document.getElementById("div2"); div2.onclick = function(){alert(1);}; div1.onclick = function(){alert(2);};//父亲 //html代码 <div id="div1"> <div id="div2"></div> </div>

现象:两个父子关系的div,然后分别加了点击事件,当我们在div2里面点击的时候,会发现弹出了一次1,接着又弹出了2,这说明点击的时候,不仅div2的事件被触发了,它的父级的点击事件也触发了,这种现象就叫做冒泡。点击了div1,自己父级的点击事件也会被触发。

事件冒泡与页面显示出来的位置是没有关系的,而是和html代码的位置有关系

再看个例子

var div1 = document.getElementById("div1"); var div2 = document.getElementById("div2") div1.onclick = function(){alert(2);}; // 父亲 //html代码 <div id="div1"> <div id="div2"></div> </div> //将两个div绝对定位在两个不同的位置,便于观察(如下图) //现象:即使只点击儿子div2,会弹出2,由此证明了当点击了儿子,父亲的点击事件被触发,执行了自己绑定的函数。由于一些人会以为显示出来儿子在父亲里面的时候,自然点了儿子相当于点了父亲,所以这个例子故意把两个盒子绝对定位在了两个不同的位置,

事件冒泡对我们几乎没有任何好处,所以我们要阻止事件冒泡,禁止之后事件只会停留在当前层

禁止事件冒泡的方法

取消事件冒泡有两种方式:

标准的W3C 方式:e.stopPropagation();这里的stopPropagation是标准的事件对象的一个方法,调用即可

非标准的IE方式:ev.cancelBubble=true; 这里的cancelBubble是 IE事件对象的属性,设为true就可以了

通常我们会封装这样一个函数

function stopBubble(e) { //如果提供了事件对象,则这是一个非IE浏览器 if ( e && e.stopPropagation ) //因此它支持W3C的stopPropagation()方法 e.stopPropagation(); else //否则,我们需要使用IE的方式来取消事件冒泡 window.event.cancelBubble = true; }

二、事件委托机制

1、概念:

就是在最外层的父级元素上,绑定事件,里面的子级元素不绑定,这样所有子元素需要的事件,通过事件冒泡原理,都委托给父级元素处理。

2、原理:事件冒泡
3、使用方法
传统的事件监听

HTML结构:

<ul id="ul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>

JS:

window.onload=function(){ var myUl=document.getElementById('ul'); var liObj=myUl.getElementsByTagName('li'); for(var i=0;i<liObj.length;i++){ list[i].addEventListener('click',function(){ this.style.backgroundColor="black"; }); } }

我们需要在ul的子元素上绑定事件,这里有一个for循环,循环遍历每一个li,在每一个li上绑定事件。 改li上事件功能很简单,就是点击li时,切换背景颜色。

通过事件委托实现事件监听

HTML

<ul id="ul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>

JS:

window.onload=function(){ var myUl=document.getElementById('ul'); myUl.addEventListener('click',function(ev){ var ev= ev||window.ev; if(ev.target.nodeName.toLocaleLowerCase()=='li'){ ev.target.style.backgroundColor="black"; } }); }

这就是简单的事件委托,在这个例子中,我们并没有直接在li上绑定事件,而是在li的父元素ul上,绑定了事件,因为ul上的事件,是通过事件冒泡,由li传递到ul,事件的冒泡顺序为:

li——>ul

因此,这里的ul点击事件的ev.target指向的是ul的子元素li。这样我们就简介的在通过ul上绑定事件,不需要遍历li,就能通过事件冒泡机制,在li上绑定事件。

事件委托的优点

(1)绑定同类子元素时,不需要循环绑定事件,减少对DOM的操作。

(2)动态添加了相同类型的子元素,如果是采用事件委托,新元素也可以被相同的事件监听到,而采用传

统的事件绑定,则新元素上并没有添加相同事件的监听。

补充说明:

1.事件


事件指可以被JavaScript侦测到的行为。即鼠标点击,页面或图像载入,鼠标悬浮于页面的某个热点之上,在表单中选取输入框,确认表单,键盘按钮等操作。事件通常与函数配合使用,当事件发生时函数才会执行。

事件名称:click/mouseover/blur等等(不带on)

响应某个事件的函数就是事件处理程序(事件侦听器)

事件处理程序函数名称:onclick/onmouseover/onblur

<button onclick="alert('Hello')"></button>

2.事件流


事件流指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。

DOM2级事件规定的事件流包括三个阶段:先捕获,后冒泡

(1) 事件捕获阶段:从外向里,先执行

(2) 处于目标阶段

(3) 事件冒泡阶段:从里向外,后执行

最新回复(0)