事件冒泡:
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)
(事件点击在子元素上 事件会一层一层向它的父元素传递 从结构上的子元素冒泡向父元素)
- focus, blur, change, submit, reset, select 等事件没有冒泡功能
//css代码
<div style="background-color: red;width: 100px;height: 100px;position: absolute;left: 0px;">
<div style="background-color: orange;width: 50px;height: 50px;position: absolute;left:100px;">
<div style="background-color: yellow;width: 25px;height: 25px;position: absolute;left: 50px;">
</div>
</div>
</div>
//例1
<script type="text/javascript">
var divs=document.getElementsByTagName("div");
divs[0].onclick=function(){
console.log("red"); //最外层的盒子
}
divs[1].onclick=function(){
console.log("orange"); //中间的盒子
}
divs[2].onclick=function(){
console.log("yellow"); //最里面的盒子
}
</script>
如图所示:
点击黄色的盒子,控制台依次输出: yellow,orange,red
点击橙色的盒子依次输出: orange,red
点击红色的盒子输出: red
事件捕获:
(IE无捕获事件)
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
(最外层先捕获 依稀向里层传递 点击的元素为事件执行元素)
触发事件捕获
元素.addEventListener('事件类型',处理函数,true);
触发顺序,
先捕获,后冒泡
与上面相同的CSS代码 我们来看一下
<script type="text/javascript">
var divs=document.getElementsByTagName("div");
//冒泡代码
divs[0].addEventListener('click',function(){
console.log("red");
},false)
divs[1].addEventListener('click',function(){
console.log("orange");
},false)
divs[2].addEventListener('click',function(){
console.log("yellow");
},false)
//捕获代码
divs[0].addEventListener('click',function(){
console.log("bu-red");
},true)
divs[1].addEventListener('click',function(){
console.log("bu-orange");
},true)
divs[2].addEventListener('click',function(){
console.log("bu-yellow");
},true)
</script>
当我们点击黄色的小方块时 显示(图1):
从红色开始捕获,因为我们点击的是黄色小方块 所以它是执行元素,在这会显示中间的会交换以下顺序。
同样的我们点击橙色的小方块时显示(图2)
图1 图2
取消冒泡事件,捕获事件:
event.stopPropagation();
不支持IE9以下(可同时取消事件捕获与冒泡)
div.onclick=function(e){ //这个函数传入一个任意的参数 这个参数是系统提供的
e.stopPropagation(); //!!!
}
比如说要去掉上面例1 橙色方块的事件冒泡可以为它加上这一个函数,这时候点击
- 此处 橙色方块取消冒泡事件 也就是说点击它不会触发它的父级产生相同的结果(阻断它下面的子元素向上传来的冒泡)
- (设置橙色的方块取消冒泡)此时点击黄色:yellow,orange 点击橙色:orange 点击红色:red
- (设置黄色的方块取消冒泡)此时点击黄色:yellow 点击橙色:yellow,orange,red 点击红色:red
divs[0].onclick=function(){
// e.stopPropagation();
console.log("red"); //最外层的盒子
}
divs[1].onclick=function(e){
e.stopPropagation(); //这个函数传入一个任意的参数 这个参数是系统提供的
console.log("orange"); //中间的盒子
}
divs[2].onclick=function(e){
//e.stopPropagation();
console.log("yellow"); //最里面的盒子
}
event.cancelBubble=true;
IE独有
div.onclick=function(e){
e.cancelBubble=true; //!!!
}
event target 事件委托
事件对象:
var event = e || window.event;
兼容处理
div.onclick=function(e){ //拿到事件触发后的事件对象
var event=e||window.event; //兼容处理
}
事件源对象:
event.target //火狐
event.srcElement //IE
var terget = event.target || event.srcElement
兼容性写法
<div class="big" style="background-color: red;width:100px;height: 100px;">
<div class="small" style="background-color: green;width: 50px;height: 50px;"></div>
</div>
<script type="text/javascript">
var div1=document.getElementsByTagName('div')[0];
var div2=document.getElementsByTagName('div')[1];
div1.onclick=function(e){
var event=e||window.event;
var target=event.target||event.srcElement;
console.log(target);
}
</script>
我们点击红色方框 再点击绿色的方框控制台的显示如下:
事件委托:
(利用事件冒泡,和事件源对象进行处理)
如下面这个例子 点击不同的 li 可以显示对应的序列:
<ul style="cursor: pointer;">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<script type="text/javascript">
var ul=document.getElementsByTagName('ul')[0];
ul.onclick=function(e){
var event=e||window.event;
var target=event.target||event.srcElement;
console.log(target.innerText);
}
</script>
优点:
- 性能 不需要循环所有的元素一个个绑定事件
- 灵活 当有新的子元素时不需要重新绑定事件