手记

js及jquery事件冒泡事件捕获处理总结

js 的addEventListerner()方法涉及事件在冒泡or捕获阶段执行

JavaSciprt事件中有两个很重要的特性:事件冒泡以及目标元素。
捕获是从上级元素到下级元素,冒泡是从下级元素到上级元素。在IE中,每个元素和window对象都有两个方法:attachEvent()和detachEvent()

var fnClick = function() {
alert("Clicked!");
}
var oDiv = document.getElementById("div1");
oDiv.attachEvent("onclick", fnClick);
oDiv.detachEvent("onclick", fnClick);
  • 利用事件冒泡---事件代理
    例如做个table元素ID是“report”,我们为这个表格添加一个事件处理器以调用editCell函数。editCell函数需要判断出传到table 来的事件的目标元素。
    function getEventTarget(e) {
    e = e || window.event;
    return e.target || e.srcElement;
    }
    function editCell(e) {
    var target = getEventTarget(e);
    if(target.tagName.toLowerCase() === 'td') {
    // DO SOMETHING WITH THE CELL
    }
    }

    不是所有的事件都能冒泡
    blur、focus、load和unload不能像其它事件一样冒泡
    如果你的代码处理mousemove事件的话你遇上性能瓶颈的风险可就大了,因为mousemove事件触发非常频繁。而mouseout则因为其怪异的表现而变得很难用事件代理来管理。

    // 语法:document.addEventListener(event, function, useCapture)
    // event    必需。描述事件名称的字符串。
    // function 必需。描述了事件触发后执行的函数。 
    //useCapture    可选。布尔值,指定事件是否 在捕获(true)或冒泡(false)阶段执行。
    document.addEventListener("click", myFunction);
    function myFunction() {
    document.getElementById("demo").innerHTML = "Hello World";
    // 判断事件冒泡or捕获
    function myFunction(e){ 
    alert(e.bubbles);
    }
    //返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口
    function myFunction(e){ 
    alert(e.currentTarget); 
    } 

    阻止事件冒泡

    
    <html>
    <head>
    <title>阻止冒泡</title>
    <style>
    body{ color:#333; font-size:12px; }
    </style>
    </head>
    <body>
    <p>什么是事件冒泡,通俗的来讲就是 我们为页面内body添加一个单击事件,同样再为页面内li元素添加一个单击事件..当你单击li的时候.<br>
    body的事件也会被触发.....因为li被包含在body元素内...你单击了li同时也单击了body...这就是事件冒泡....<br />
    在有些时候.我们要阻止这种情况发生...也就是单击li事件.不会触发body的事件.... 这就叫阻止冒泡!
    <div id="a">
    <ul id="lia">请单击下面的列表.会触发body事件
    <li>项目1</li>
    <li>项目2</li>
    <li>项目3</li>
    </ul>
<ul id="lib">请单下面的列表.不会触发body事件.
    <li>项目1</li>
    <li>项目2</li>
    <li>项目3</li>
</ul>

</div>
<script language="javascript">
document.body.onclick = function(){//首先为body元素绑定一个单击事件
alert("BODY事件");//单击页面即弹出对话框
}

function att_Event(){//为第一组li元素绑定onclick事件
var li = document.getElementById("lia").getElementsByTagName("li");
for(var i=0;i<li.length;i++){
li[i].onclick = function(){
alert("Li事件");
}
}
}

function att_Event_b(){//为第二组li元素绑定onclick事件
var li = document.getElementById("lib").getElementsByTagName("li");
for(var i=0;i<li.length;i++){
li[i].onclick = function(e){
alert("Li事件");
stopBubble(e); //运行阻止冒泡的函数
}
}
}
//该函数的功能用来阻止事件冒泡.并兼容多浏览器
function stopBubble(e){
//如果传入了事件对象.那么就是非IE浏览器
if(e && e.stopPropagation){
//因此它支持W3C的stopPropation()方法
e.stopPropagation();
}
else
{
//否则,我们得使用IE的方式来取消事件冒泡
window.event.cancelBubble = true;
}
}

window.onload = function(){
att_Event();
att_Event_b();
}
</script>
</body>
</html>

## jquery

// 语法: event.stopPropagation(),event必选 参数,来自事件绑定函数。
但是这个方法对使用live绑定的事件没有作用,需要一个更简单的方法阻止事件冒泡:return false;需要如下处理:
$(this).after("Another paragraph!");
return false; });
//实例
<script src="https://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$("span").click(function(event){
event.stopPropagation();
alert("The span element was clicked.");
});
$("p").click(function(event){
alert("The p element was clicked.");
});
$("div").click(function(){
alert("The div element was clicked.");
});
});
</script>
</head>
<body>
<div style="height:100px;width:500px;padding:10px;border:1px solid blue;background-color:lightblue;">
This is a div element.
<p style="background-color:pink">This is a p element, in the div element. <br>
<span style="background-color:orange">This is a span element in the p and the div element.</span></p>
</div>
</body>

### vue框架实现
>  在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在 methods 中轻松实现这点,但更好的方式是:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
Vue.js 为 v-on 提供了 事件修饰符。通过由点(.)表示的指令后缀来调用修饰符。
.stop
.prevent
.capture
.self
.once

注意:此时只针对vue实例内方法有效,对原生事件(非写在methods内的事件)无效,这也是DOM操作库和数据驱动框架容易冲突的隐患之一。

<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

3人推荐
随时随地看视频
慕课网APP