javascript原生提供的addEventListener()允许我们设置事件的类型冒泡还是捕获,
JQuery中的事件绑定都是属于冒泡类型,
<div id="parent" style="width:500px;height:500px;background-color:#000;">
<div id="child" style="width:300px;height:300px;background-color:red;"></div>
</div>
<script>
$(function () {
$("#child").click(function (e) {
alert("child");
})
$("#parent").click(function (e) {
alert("parent");
})
</script>
点击child,依次弹出窗口child->parent
阻止事件传播的2种方式。
1) event.stopPropagation();
<div id="parent" style="width:500px;height:500px;background-color:#000;">
<div id="child" style="width:300px;height:300px;background-color:red;"></div>
</div>
<script>
$(function () {
$("#child").click(function (e) {
alert("child");
event.stopPropagation();
})
$("#parent").click(function (e) {
alert("parent");
})
</script>
2) 事件处理函数的返回false
<div id="parent" style="width:500px;height:500px;background-color:#000;">
<div id="child" style="width:300px;height:300px;background-color:red;"></div>
</div>
<script>
$(function () {
$("#child").click(function (e) {
alert("child");
return false;
})
$("#parent").click(function (e) {
alert("parent");
})
</script>
真实的应用场景:
table分页展示数据,代码如下,要求点击th按id排序,点击tbody内的td弹出用户详细信息信息,点击删除弹出确认删除弹窗:
Index.cshtml里有方法的实现,每个方法都要阻止冒泡。
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>序号</th>
<th>用户ID</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@{ Html.RenderPartial("~/_ModelList.cshtml"); }
</tbody>
</table>
@section scripts{
function Del(id,event){
event = event || window.event;
...
业务逻辑
...
event.stopPropagation();//阻止冒泡
}
function ShowUser(userid,event){
event = event || window.event;
...
业务逻辑
...
event.stopPropagation();//阻止冒泡
}
function OrderBy(){
...
业务逻辑
...
}
$(th).click(function(e){
orderby();
})
}
_ModelList.cshtml
@{
foreach (var item in Model)
{
<tr>
<td onclick="ShowUser('@item.userid',event)">
@item.id
</td>
<td onclick="ShowUser('@item.userid',event)">
@item.userid
</td>
<td onclick="ShowUser('@item.userid',event)">
<a class="del" onclick="Del('@item.id',event)">删除</a>
</td>
</tr>
}
}
点击th标签排序的功能我们是这样实现的
但是到了信息展示和删除的功能,我们确无奈使用了DOM元素事件属性。
因为表格用到了AJAX分页组件,为了保证方法在每页都有效果,只好为每个td标签和a标签都绑定一次。
用甘露模式优化后的代码:
1) _ModelList.cshtml 去掉DOM元素事件属性
@{
foreach (var item in Model)
{
<tr>
<td>
@item.id
</td>
<td>
@item.userid
</td>
<td>
<a class="del">删除</a>
</td>
</tr>
}
}
2)删除Index.cshtml中原来的方法,并添加一个table的点击事件统一处理
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>序号</th>
<th>用户ID</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@{ Html.RenderPartial("~/_ModelList.cshtml"); }
</tbody>
</table>
@section scripts{
$("table").click(function (e) {
switch (e.target.tagName.toLowerCase()) {
case "th":
do 排序;
break;
case "td":
do 通过jQuery选择器找到userid
do 信息展示;
break;
case "a":
do 通过jQuery选择器找到id
do 删除;
break;
default: ; break;
}
})
}