`
sigh0829
  • 浏览: 5370 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

转帖:jQuery事件处理: 别再乱用“return false”了

 
阅读更多
原地址 :http://www.jqfans.com/thread-136-1-1.html

最近在写程序的时候经常用到 return false 看了这个文章后 感受颇多 就转过来了 希望对大家有帮助
原文:http://heikezhi.com/2011/04/18/jquery-events-stop-misusing-return-false/


可能在你刚开始学习关于jQuery事件处理时,看到的第一个例子就是关于如何阻止浏览器执行默认行为,比如下面这段演示click事件的代码:

$("a.toggle").click( function () {
	$("#mydiv").toggle();
	return false;
});

这个函数使用toggle来显示或者隐藏#mydiv,然后阻止浏览器继续访问href中指定的链接。

像上面这样的例子会让用户养成使用“return false”来阻止浏览器执行默认行为的坏习惯,在这篇文章里,我将会讨论关于阻止浏览器执行默认行为的两个非常重要的主题:

选择正确的方法: return false还是preventDefault,stopPropagation或者stopImmediatePropagation
选择合适的位置,开始,结束,还是中间某个地方:你应该在事件回调的哪个部分取消浏览器执行默认行为?
注意:当我在这篇文章中提到event bubbling(事件冒泡),我想表达的是大部分事件都是先在初始DOM上触发,然后再通过DOM树往上,在每一级父元素上触发,事件不会在兄弟节点或是子节点上冒泡(当事件向下冒泡时,我们叫它事件捕捉(event capturing)),你可以在这里了解更多关于事件起泡和捕捉的介绍。

选择正确的方法

“return false”之所以被误用的如此厉害,是因为它看起来像是完成了我们交给它的工作,浏览器不会再将我们重定向到href中的链接,表单也不会被继续提交,但这么做到底有什么不对呢?

”return false“到底做了什么?

当你每次调用”return false“的时候,它实际上做了3件事情:

event.preventDefault();
event.stopPropagation();
停止回调函数执行并立即返回。
“等等”,你叫了起来!我只是想让浏览器停止继续执行默认行为而已,我不需要它去做另外2件事。

这3件事中用来阻止浏览器继续执行默认行为的只有preventDefault,除非你想要停止事件冒泡,否则使用return false会为你的代码埋下很大的隐患,让我们通过一个真实的例子来看看这样的误用会造成什么后果:

这是我们用来演示的HTML:
<div class="post">  
<h2><a href="http://heikezhi.com/path/to/page">My Page</a></h2>  
<div class="content">      Teaser text...    </div>  
</div>  
<div class="post">  
<h2><a href="http://heikezhi.com/path/to/other_page">My Other Page</a></h2>  
<div class="content">      Teaser text...    </div>  
</div>
 


现在假设我们想要在用户点击文章标题时,将文章动态载入到div.contentd中:
jQuery(document).ready( function ($) {
	$("div.post h2 a").click( function () {
		var a    = $(this), href = a.attr('href'),content  = a.parent().next();
		content.load(href + " #content");
		return false;
	});
});



这段代码可以正常工作(至少目前是),但如果我们顺着这个思路继续,如果我想要在用户点击了一个div.post元素(或者任何一个它的子元素)时,给它加上一个active类,我就需要给div.post增加了一个click回调:

var posts = $("div.post");
posts.click( function () {
	posts.removeClass("active");
	$(this).addClass("active");
});


现在,如果我们点击一个帖子的标题,这段代码会工作吗?答案是不会,因为我们在标题的click回调里使用了return false而不是我们应该使用的,”return false“等于event.preventDefault();加event.stopPropagation();,所以事件冒泡就被终止了,click事件不会被冒泡到div.post上,我们为它添加的事件回调当然也就不会被调用了。

如果我们把它和live或者delegate事件混在一起使用时,情况就更糟了。

$("a").click( function () {
	return false;
});
$("a").live("click", function () {
});



那么我们真正需要的是什么呢?

preventDefault()

大多数情况下,当你使用return false时,你其实真正需要的是e.preventDefault()。要使用e.preventDefault,你需要确保你传递了event参数到你的回掉函数中(在这个例子里,就是那个e):

$("a").click( function (e) {
	e.preventDefault();
});


它会替我们完成所有工作,但不会阻止父节点继续处理事件,要记住,你放在代码中的限制越少,你的代码就越灵活,也就越易于维护。

stopPropagation()

但有些情况下,你有可能需要停止事件冒泡,让我们看看下面的例子:


<div class="post"> Normal text and then a <a href="http://heikezhi.com/path">link</a> and then more text.  </div>  



现在,让我们假设如果你点了div上除了a链接之外的地方,我们希望能发生点什么事情(比如改变下背景什么的),但是不能影响用户点击a链接的行为(从可用性的角度,这个例子不怎么好,你可能不希望用户点击别的地方时发生任何事情)。
$("div.post").click( function () {
});
$("div.post a").click( function (e) {
	e.stopPropagation();
});



在这种情况下,如果我们使用return false,div的click事件不会被触发,但是用户也不会到达他们点的那个链接。

stopImmediatePropagation()

这个方法会停止一个事件继续执行,即使当前的对象上还绑定了其它处理函数,所有绑定在一个对象上的事件会按绑定顺序执行,看看下面的例子:


$("div a").click( function () {    // Do something
});
$("div a").click( function (e) {    // Do something else
	e.stopImmediatePropagation();
});
$("div a").click( function () {    // THIS NEVER FIRES
});
$("div").click( function () {    // THIS NEVER FIRES
});



你可能会觉得这个例子看起来很别扭,没错,尽管如此,但有时这的确会发生,如果你的代码非常复杂,那么不同的widgets和plugin就有可能在同一个对象上添加事件,如果遇到这种情况,那你就很有必要理解和使用stopImmediatePropagation。

return false

只有当你同时需要preventDefault和stopPropagation,并且你的代码可以接受直到你的回调执行完成才停止执行浏览器的默认行为,那你就可以使用”return false“。但我强烈建议你别在写给其它jQuery开发者的演示代码中使用这个方法,因为这会造成更多误用,只有在你确信非用不可的情况下再去使用”return false“。

选择适当的位置

如果你使用了”return false“,它只会在你的回调函数执行结束才去取消浏览器的默认行为,但是使用e.preventDefault,我们有更多的选择,它可以随时停止浏览器执行默认动作,而不管你将它放在函数的哪个部分。

1. 开发阶段,你应该总是将它放在第一行。你最不想做的事情可能就是你正在调试将一个form改成ajax提交的时候,它却已经被按照老方法提交了。

2.产品阶段,如果你采用了渐进增强(progressive enhancement),那就把它放到回调的结束位置,或者是逻辑终点,如果在一个普通页面采用渐进增强,那你就需要在服务器端考虑如果浏览器不支持JS时(或者被禁用时),对链接的click事件和表单的提交事件的处理。这里的好处是,我们不考虑关闭JS的情况,只考虑支持js时的强狂,如果你的回调代码出错抛出了异常,让我们看看下面的代码:
var data = {};
$("a").click( function (e) {
	e.preventDefault(); // cancel default behavior    // Throws an error because `my` is undefined
	$("body").append(data.my.link);    // The original link doesn't work AND the "cool"    // JavaScript has broken. The user is left with NOTHING!
});



现在,让我们看看同样的事件,把preventDefault调用放在底部的效果:
var data = {};
$("a").click( function (e) {    // Throws an error because `my` is undefined
	$("body").append(data.my.link);      // This line is never reached, and your website    // falls back to using the `href` instead of this    // "cool" broken JavaScript!
	e.preventDefault(); // cancel default behavior
});



这对表单提交也同样有效,你可以更好的应对出错的情况,别指望你的代码一直正常工作,在发生错误时有正确的应对总胜过假设代码不会出错。

3. 在产品阶段,如果功能这设计JS,那就还应该放在第一行。

记住,不必非得是函数的第一行,但是越早越好,这里的原则是:如果函数的功能是通过JS实现的(不涉及服务端交互),那就没必要考虑兼容,在这种情况下,添加在第一行可以防止URL中出现#字符,但显然,你还是应该尽可能多的增加些错误处理代码,以防止用户在出错时变得不知所措。

结论

我希望这篇文章传达的信息足够你在需要阻止浏览器执行默认行为时做出正确的选择。记住,只有当你真的明白你在做什么时,才使用”return false“,并确保你是在函数的正确位置调用了相应的代码。最后,尽可能保持代码的灵活性,尽量不要再用“return false”了!
分享到:
评论

相关推荐

    [转帖]jQuery实现省市联动

    2. **jQuery事件监听**:使用`$(document).ready()`确保DOM加载完成后,绑定`change`事件处理函数。 ```javascript $(document).ready(function() { $('#province').on('change', function() { // 在这里获取城市...

    转帖:液晶显示器原理与维修手册

    ### 液晶显示器原理与维修手册核心知识点详解 #### 一、液晶显示器的主要技术指标 ...同时,电路工作原理涉及信号处理、控制系统和电源管理等多个方面,理解这些原理对于维修和优化液晶显示器至关重要。

    转帖:Android应用的自动升级、更新模块的实现docx.docx

    6. **处理异常**: 检查和下载过程中可能出现的网络错误、存储空间不足等问题需要有合适的错误处理和反馈机制。 **三、具体实现** 1. **版本检查接口**: 设计一个HTTP接口或提供一个版本信息文件,如`...

    转帖:我的职场十年,IT人很值得借鉴呀

    例如,从传统的软件开发到新兴的大数据处理或人工智能等领域,都需要不断的学习和实践。 ### 二、团队合作与沟通 文章中提到了与同事之间的沟通问题,尤其是当面对复杂的技术挑战时,良好的沟通技巧对于解决问题至...

    论坛转帖工具.rar

    标题中的“论坛转帖工具.rar”表明这是一个用于在论坛之间转移帖子的软件工具,通常用于帮助用户方便地将一个论坛的帖子内容复制到另一个论坛,可能是为了分享信息、讨论或保存重要的帖子。这类工具可能包括自动抓取...

    编辑人员转帖去水印工具

    在IT行业中,编辑人员在处理图像或视频时经常会遇到水印问题。水印可能是他人版权的标识,也可能是不希望展示的信息,去除水印成为了一项必要的技能。本篇文章将详细探讨“编辑人员转帖去水印工具”,并介绍如何使用...

    UBB论坛转帖圣手.exe

    UBB论坛转帖圣手.exeUBB论坛转帖圣手.exe

    用PHP批量生成图片缩略图——活跃论坛转帖

    在论坛转帖的场景下,这个过程可能会更复杂,因为需要考虑图片的显示顺序、缓存策略、错误处理等因素。例如,可能需要在数据库中记录每个图片的缩略图路径,以便快速加载,同时处理上传失败或网络中断的情况。 总的...

    转帖--oracle分析函数+PLSQL小结

    Oracle分析函数是数据库查询中的一个强大工具,它们在处理数据集时提供了高级的聚合功能,可以对一组行进行计算,并返回单个值或一组值。分析函数与聚合函数(如SUM, AVG, COUNT等)类似,但有显著的区别:聚合函数...

    discuz X2转帖工具、采集工具

    3. 原创保护:在转帖时,可以进行必要的处理,如添加引用、链接原文,尊重原作者,避免侵犯版权。 三、使用注意事项 1. 法律合规:使用这类工具时,必须确保所发布的帖子内容合法,不侵犯他人权益,遵循网络道德...

    贴吧转帖工具

    【贴吧转帖工具】是一种专为百度贴吧用户设计的便捷工具,主要用于提高用户在贴吧中的互动效率。通过这款工具,用户可以实现一键转帖和一键8经验签到的功能,极大地简化了传统操作流程,节省了用户的时间,提升了...

    [转帖] 用C# Generator解决Hanoi塔问题

    《C# Generator解构Hanoi塔问题》 在编程领域,Hanoi塔是一个经典的递归问题,它展示了如何通过分治策略解决复杂...理解并掌握Generator的使用,对于提升C#编程能力,特别是处理复杂逻辑和优化性能方面具有重要意义。

    农商银行贴现、转帖现及再贴现操作细则.doc

    《农商银行贴现、转帖现及再贴现操作细则》是针对农村商业银行在处理银行承兑汇票贴现、转贴现买入、卖出以及再贴现业务时的操作规范,旨在规范票据业务流程,保障业务的快速健康发展。以下是根据文档内容提炼的知识...

    [转帖]世界编程大赛第一名写的程序

    例如,在处理大量数据时,哈希表可以提供快速的查找速度;而在解决最短路径问题时,Dijkstra算法或Floyd-Warshall算法则是不二之选。 2. **代码优化**:竞赛中的时间限制意味着代码的运行效率至关重要。优化代码...

    转帖经典---JAVA设计模式

    《转帖经典---JAVA设计模式》这本书或资料可能涵盖了这些模式的详细解释、示例代码以及如何在实际项目中应用这些模式。通过学习和理解这些设计模式,开发者能够更好地设计和重构软件,提升代码质量。

    一键转帖功能插件 for 帝国CMS 6.0 GBK utf8 V1.0.rar

    《一键转帖功能插件 for 帝国CMS 6.0 GBK utf8 V1.0》 本文将深入探讨“一键转帖功能插件”在帝国CMS 6.0系统中的应用与实现,该插件适用于GBK及UTF-8编码环境,旨在提升网站内容的分享与传播效率。我们将从安装...

    转帖图片提取工具 v1.0.zip

    转帖图片提取工具可以对论坛图片附件信息进行清除,只保留图片代码,操作很简单,推荐有需要转帖图片工具的朋友下载 转帖图片提取工具使用方法: 将IP138上处理过的东西复制到上方的编辑框内,点击只要图片,下面...

    一键转帖功能插件 for 帝国CMS v1.0.rar

    "copyto.js" 是一个JavaScript文件,它的主要作用是在前端实现一键转帖的功能,可能包含事件监听、内容提取、以及与服务器交互的逻辑。"copyto.php" 是后端处理脚本,它接收来自前端的请求,处理数据,例如验证用户...

    转帖工具插件 for PHPwind 7.5 正式版.rar

    "转帖工具插件 for PHPwind 7.5 正式版" 是专门为 PHPwind 7.5 版本设计的一个功能插件,旨在提供便捷的帖子转移功能,帮助管理员或者用户将内容从一个地方轻松移动到另一个地方,而无需直接编辑论坛的原始文件。...

Global site tag (gtag.js) - Google Analytics