文档章节

JS_stopPropagation, preventDefault 和 return false

喵王不瞌睡
 喵王不瞌睡
发布于 2014/12/07 19:27
字数 933
阅读 56
收藏 3

因为有父, 子节点同在, 因为有监听事件和浏览器默认动作之分. 使用 JavaScript 时为了达到预期效果经常需要阻止事件和动作执行. 一般我们会用到三种方法, 分别是 stopPropagation(), preventDefault() 和 return false. 它们之间有什么区别, 该何时使用呢? 将在本文中进行讲解.


术语

监听事件, 在在节点上能被监听的页面操作. 如: select 节点的 change 事件, a 节点的 click 事件.
浏览器默认动作, 指特定页面元素上带有的功能. 如: 点击 a 链接节点的跳转动作, 表单提交动作.

stopPropagation()

因为事件可以在各层级的节点中传递, 不管是冒泡还是捕获, 有时我们希望事件在特定节点执行完之后不再传递, 可以使用事件对象的 stopPropagation() 方法.

假设页面上存在一个浮动弹出层, 显示在最前面, 当点击弹出层以外页面区域时, 隐藏弹出层. 为了做到这样的效果, 我们会监听 documentElement 的 click 事件, 一旦事件被触发即隐藏弹出层. 但是...

这显然存在问题. 当用户点击弹出层时, 我们不希望它隐藏掉. 但因为事件的冒泡传递, documentElement 的 click 事件也会被触发. 这个时候, 我们可以监听弹出层的 click 事件, 并使用 stopPropagation() 方法阻止冒泡. 请参考下面的代码.

// 在弹出对话框上点击时, 不进行任何页面操作, 并阻止冒泡
document.getElementById('dialog').onclick = function(ev) {
 ev.stopPropagation();
};
 
// 在 documentElement 节点上监听到点击事件时, 隐藏对话框
document.documentElement.onclick = function(ev) {
 document.getElementById('dialog').style.display = 'none';
};
stopPropagation() 相当好用, 可是 IE8 及以前版本都不支持. IE 的事件对象包含特有的属性 cancelBubble, 只要将它赋值为 false 即可阻止事件继续. 如:

// 在弹出对话框上点击时, 不进行任何页面操作, 并阻止冒泡
document.getElementById('dialog').onclick = function(ev) {
 ev.cancelBubble = false;
};
preventDefault()

一个带事件监听的链接代码如下:

<a href="http://w3c.org" onclick="alert('JavaScript Click Event');">点击链接</a>
点击该链接, 显示对话框后跳转页面. 由此可知, 除了执行监听事件还会触发浏览器默认动作; 执行监听事件在前, 触发浏览器默认动作在后.

这里有个经典示例, 我们希望点击链接在新窗口打开页面, 但不希望当前页面跳转. 这个时候可以使用 preventDefault() 阻止后面将要执行的浏览器默认动作.

<a id="link" href="http://w3c.org">W3C 首页链接</a>
 
<script>
// 在新窗口, 打开页面
document.getElementById('link').onclick = function(ev) {
 // 阻止浏览器默认动作 (页面跳转)
 ev.preventDefault();
 // 在新窗口打开页面
 window.open(this.href);
};
</script>
return false

退出执行, return false 之后的所有触发事件和动作都不会被执行. 有时候 return false 可以用来替代 stopPropagation() 和 preventDefault(), 比如我们上面新窗口打开链接的例子, 如:

<a id="link" href="http://w3c.org">W3C 首页链接</a>
 
<script>
// 在新窗口, 打开页面
document.getElementById('link').onclick = function(ev) {
 // 在新窗口打开页面
 window.open(this.href);
 // 退出执行 (在监听事件之后执行的浏览器默认动作将不会被执行)
 return false;
};
</script>
有人认为 return false = stopPropagation() + preventDefault(), 其实是错的. return false 不但阻止事件, 还可以返回对象, 跳出循环等... 方便地一刀切而不够灵活, 滥用易出错.

后话

因为习惯用 return false 来阻止事件, 最近在搞手机 Web 的时候遇到一些问题, 很是难堪. 写下此文当作笔记, 提醒自己.

本文转载自:http://www.neoease.com/stoppropagation-and-preventdefault-and-return-false/

喵王不瞌睡
粉丝 12
博文 168
码字总数 51103
作品 0
浦东
个人站长
私信 提问
jQuery事件处理: 别再乱用“return false”了

可能在你刚开始学习关于jQuery事件处理时,看到的第一个例子就是关于如何阻止浏览器执行默认行为,比如下面这段演示click事件的代码: view plaincopy to clipboardprint? $("a.toggle").cl...

索隆
2012/09/18
1.8K
1
深度解析JavaScript事件对象

这篇文章主要介绍了JavaScript事件对象,结合实例形式深入分析了javascript DOM、IE及其他浏览器相关事件对象操作技巧与注意事项,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可...

前端攻城小牛
2019/01/16
434
1
jQuery中return false,e.preventDefault(),e.stopPropa

e.stopPropagation()阻止事件冒泡 <head> <title></title> <script src="Scripts/jQuery-1.4.1.js" type="text/JavaScript"></script> </head> <body> <table> <tr> <td><span>冒泡事件测试<......

张悟空
2016/04/22
86
0
前端杂谈: DOM event 原理

前端杂谈: DOM event 原理 DOM 事件是前端开发者习以为常的东西. 事件的监听和触发使用起来都非常方便, 但是他们的原理是什么呢? 浏览器是怎样处理 event绑定和触发的呢? 让我们通过实现一个...

ssthouse_hust
2018/11/22
205
0
跨浏览器的javascript事件和对象的封装

跨浏览器的事件处理程序 DOM0级处理事件 将一个函数赋值给一个事件处理程序属性 事件流: 冒泡阶段 使用: 1、为元素增加事件: 2、删除事件: DOM2级事件处理程序 两个方法: 和 三个参数:...

小婉
2019/06/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android实现App版本自动更新

现在很多的App中都会有一个检查版本的功能。例如斗鱼TV App的设置界面下: 当我们点击检查更新的时候,就会向服务器发起版本检测的请求。一般的处理方式是:服务器返回的App版本与当前手机安...

shzwork
今天
55
0
npm 发布webpack插件 webpack-html-cdn-plugin

初始化一个项目 npm init 切换到npm源 淘宝 npm config set registry https://registry.npm.taobao.org npm npm config set registry http://registry.npmjs.org 登录 npm login 登录状态......

阿豪boy
今天
83
0
java基础(16)递归

一.说明 递归:方法内调用自己 public static void run1(){ //递归 run1(); } 二.入门: 三.执行流程: 四.无限循环:经常用 无限递归不要轻易使用,无限递归的终点是:栈内存溢出错误 五.递...

煌sir
今天
61
0
REST接口设计规范总结

URI格式规范 URI中尽量使用连字符”-“代替下划线”_”的使用 URI中统一使用小写字母 URI中不要包含文件(脚本)的扩展名 URI命名规范 文档(Document)类型的资源用名词(短语)单数命名 集合(Co...

Treize
今天
65
0
CentOS-配置YUM源加速(阿里云、Nexus3)

备份本地源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 配置CentOS6 $ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/......

-自由人生-
今天
92
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部