Js 冒泡事件阻止实现代码


Posted in Javascript onJanuary 27, 2013

1. 事件目标

现在,事件处理程序中的变量event保存着事件对象。而event.target属性保存着发生事件的目标元素。这个属性是DOM API中规定的,但是没有被所有浏览器实现 。jQuery对这个事件对象进行了必要的扩展,从而在任何浏览器中都能够使用这个属性。通过.target,可以确定DOM中首先接收到事件的元素(即实际被单击的元素)。而且,我们知道this引用的是处理事件的DOM元素,所以可以编写下列代码:

$(document).ready(function(){
 $('#switcher').click(function(event){
  $('#switcher .button').toggleClass('hidden');
  })
 })$(document).ready(function(){
 $('#switcher').click(function(event){
  if(event.target==this){
  $('#switcher .button').toggleClass('hidden');
  }
  })
 })
 

此时的代码确保了被单击的元素是<div id="switcher"> ,而不是其他后代元素。现在,单击按钮不会再折叠样式转换器,而单击边框则会触发折叠操作。但是,单击标签同样什么也不会发生,因为它也是一个后代元素。实际上,我们可以不把检查代码放在这里,而是通过修改按钮的行为来达到目标 。

2. 停止事件传播

事件对象还提供了一个.stopPropagation()方法,该方法可以完全阻止事件冒泡。与.target类似,这个方法也是一种纯JavaScript特性,但在跨浏览器的环境中则无法安全地使用 。不过,只要我们通过jQuery来注册所有的事件处理程序,就可以放心地使用这个方法。
下面,我们会删除刚才添加的检查语句event.target == this,并在按钮的单击处理程序中添加一些代码:

$(document).ready(function(){
 $('#switcher .button').click(funtion(event){
  //……
   event.stopPropagation();
  })
 })

  同以前一样,需要为用作单击处理程序的函数添加一个参数,以便访问事件对象。然后,通过简单地调用event.stopPropagation()就可以避免其他所有DOM元素响应这个事件。这样一来,单击按钮的事件会被按钮处理,而且只会被按钮处理。单击样式转换器的其他地方则可以折叠和扩展整个区域。

3. 默认操作

如果我们把单击事件处理程序注册到一个锚元素,而不是一个外层的<div>上,那么就要面对另外一个问题:当用户单击链接时,浏览器会加载一个新页面。这种行为与我们讨论的事件处理程序不是同一个概念,它是单击锚元素的默认操作。类似地,当用户在编辑完表单后按下回车键时,会触发表单的submit事件,在此事件发生后,表单提交才会真正发生。
如果我们不希望执行这种默认操作,那么在事件对象上调用.stopPropagation()方法也无济于事,因为默认操作不是在正常的事件传播流中发生的。在这种情况下,.preventDefault()方法则可以在触发默认操作之前终止事件 。
提示 当在事件的环境中完成了某些验证之后,通常会用到.preventDefault()。例如,在表单提交期间,我们会对用户是否填写了必填字段进行检查,如果用户没有填写相应字段,那么就需要阻止默认操作。我们将在第8章详细讨论表单验证。
事件传播和默认操作是相互独立的两套机制,在二者任何一方发生时,都可以终止另一方。如果想要同时停止事件传播和默认操作,可以在事件处理程序中返回false,这是对在事件对象上同时调用.stopPropagation()和.preventDefault()的一种简写方式。

补充:

//单击按钮事件(改变文字样式)
$(document).ready(function() {
   $('#switcher .button').click(function() {
     $('body').removeClass();
     if (this.id == 'switcher-narrow') {
       $('body').addClass('narrow');
     }
     else if (this.id == 'switcher-large') {
       $('body').addClass('large');
     }     $('#switcher .button').removeClass('selected');
     $(this).addClass('selected');
   });
});

//单击按钮外层div出发事件(隐藏按钮)
$(document).ready(function() {
   $('#switcher').click(function() {
     $('#switcher .button').toggleClass('hidden');
   });
});

现在的问题是,当点击了按钮时,同时触发了隐藏按钮事件。这是事件冒泡导致。
为了阻止事件冒泡,需要为隐藏按钮函数添加一个参数:
$(document).ready(function() {
   $('#switcher').click(function(even) {
     if(even.target==this){
       $('#switcher .button').toggleClass('hidden');
     }
   });
});

even保存事件对象,even.target属性保存发生事件的目标元素。可以确定DOM中首先接收到事件的元素。此时代码确保了被单击的是<div id="switcher">,而不是其后代元素。

也可以这样处理,通过修改按钮的行为来达到目的。

$(document).ready(function() {
   $('#switcher .button').click(function(even) {
     $('body').removeClass();
     if (this.id == 'switcher-narrow') {
       $('body').addClass('narrow');
     }
     else if (this.id == 'switcher-large') {
       $('body').addClass('large');
     }     $('#switcher .button').removeClass('selected');
     $(this).addClass('selected');
     even.stopPropagation();
   });
});

用JS阻止事件冒泡

事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。
可以用JS来阻止js事件冒泡。因为浏览器的差异IE和FF的JS写法有点不一样。
IE用cancelBubble=true来阻止而FF下需要用stopPropagation方法。
下一下完整的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script type="text/javascript">
function aaaclick(){
 alert("td click");
}
function bbbclick(evt){
 alert("td click");
 if (window.event) {
  event.cancelBubble = true;
 }else if (evt){
  evt.stopPropagation();
 }
}
function trclick(){
 alert("tr click");
}
function tableclick(){
 alert("table click");
}
</script>
<style type="text/css">
<!--
.tab {
 border: 1px solid #0066FF;
 cellpadding:0px;
 cellspacing:0px;
}
.tab td{
 border: 1px solid #0066FF;
}
-->
</style>
</head>
<body>
<p>点击aaaa会触发上层的onclick事件,点击bbbb不会触发上层onclick事件</p>
<table width="204" onclick="tableclick()" class="tab">
  <tr >
    <td width="96"> </td>
    <td width="96"> </td>
  </tr>
  <tr onclick="trclick()">
    <td onclick="aaaclick()">aaaa</td>
    <td onclick="bbbclick(event)">bbbbb</td>
  </tr>
  <tr>
    <td> </td>
    <td> </td>
  </tr>
</table>
</body>
</html>
Javascript 相关文章推荐
通过Jscript中@cc_on 语句识别IE浏览器及版本的代码
May 07 Javascript
基于jquery实现的移入页面上空文本框时,让它变为焦点,移出清除焦点
Jul 26 Javascript
js控制页面的全屏展示和退出全屏显示的方法
Mar 10 Javascript
javascript框架设计之框架分类及主要功能
Jun 23 Javascript
理解和运用JavaScript的闭包机制
Aug 13 Javascript
jQuery动画效果相关方法实例分析
Dec 31 Javascript
深入浅析jQuery对象$.html
Aug 22 Javascript
JavaScript鼠标特效大全
Sep 13 Javascript
详解AngularJS用Interceptors来统一处理HTTP请求和响应
Jun 08 Javascript
浅谈vue,angular,react数据双向绑定原理分析
Nov 28 Javascript
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
Mar 13 Javascript
关于Vue源码vm.$watch()内部原理详解
Apr 26 Javascript
javascript里模拟sleep(两种实现方式)
Jan 25 #Javascript
调试Javascript代码(浏览器F12及VS中debugger关键字)
Jan 25 #Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
Jan 25 #Javascript
js隐藏与显示回到顶部按钮及window.onscroll事件应用
Jan 25 #Javascript
jquery移除button的inline onclick事件(已测试及兼容浏览器)
Jan 25 #Javascript
javascript表单验证 - Parsley.js使用和配置
Jan 25 #Javascript
THREE.JS入门教程(6)创建自己的全景图实现步骤
Jan 25 #Javascript
You might like
全国FM电台频率大全 - 26 西藏自治区
2020/03/11 无线电
PHP编程网上资源导航
2006/10/09 PHP
php实现的DateDiff和DateAdd时间函数代码分享
2014/08/16 PHP
mysql desc(DESCRIBE)命令实例讲解
2016/09/24 PHP
使用EXT实现无刷新动态调用股票信息
2008/11/01 Javascript
Extjs ajax同步请求时post方式参数发送方式
2009/08/05 Javascript
Javascript类库的顶层对象名用户体验分析
2010/10/24 Javascript
jquery form 加载数据示例
2014/04/21 Javascript
抛弃Nginx使用nodejs做反向代理服务器
2014/07/17 NodeJs
indexOf 和 lastIndexOf 使用示例介绍
2014/09/02 Javascript
js实现编辑div节点名称的方法
2014/12/17 Javascript
JS模拟键盘打字效果的方法
2015/08/05 Javascript
Javascript基础知识盲点总结之函数
2016/05/15 Javascript
hovertree插件实现二级树形菜单(简单实用)
2016/12/28 Javascript
jQuery弹出窗口简单实现代码
2017/03/09 Javascript
使用Bootstrap打造特色进度条效果
2017/05/02 Javascript
React-router v4 路由配置方法小结
2017/08/08 Javascript
解决jquery validate 验证不通过后验证正确的信息仍残留在label上的方法
2019/08/27 jQuery
vue+element 实现商城主题开发的示例代码
2020/03/26 Javascript
vue使用exif获取图片旋转,压缩的示例代码
2020/12/11 Vue.js
使用setup.py安装python包和卸载python包的方法
2013/11/27 Python
python在windows下实现备份程序实例
2014/07/04 Python
Python 抓取动态网页内容方案详解
2014/12/25 Python
Python中的pass语句使用方法讲解
2015/05/14 Python
Python中存取文件的4种不同操作
2018/07/02 Python
Python面向对象之静态属性、类方法与静态方法分析
2018/08/24 Python
python标准库os库的函数介绍
2020/02/12 Python
Pytest单元测试框架如何实现参数化
2020/09/05 Python
浅析canvas元素的html尺寸和css尺寸对元素视觉的影响
2019/07/22 HTML / CSS
50道外企软件测试面试题
2014/08/18 面试题
《毛主席在花山》教学反思
2014/04/20 职场文书
村委会贫困证明范文
2014/09/21 职场文书
作风建设剖析材料
2014/10/06 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
PyMongo 查询数据的实现
2021/06/28 Python
C3 线性化算法与 MRO之Python中的多继承
2021/10/05 Python