大多数情况下,当你使用return false时,你其实真正需要的是e.preventDefault()。要使用e.preventDefault,你需要确保你传递了event参数到你的回掉函数中(在这个例子里,就是那个e):
复制代码 代码如下:
$("a").click(function (e) {
// e == our event data
e.preventDefault();
});
它会替我们完成所有工作,但不会阻止父节点继续处理事件,要记住,你放在代码中的限制越少,你的代码就越灵活,也就越易于维护。
stopPropagation()
但有些情况下,你有可能需要停止事件冒泡,让我们看看下面的例子:
复制代码 代码如下:
<div>
Normal text and then a <a href="https://jb51.net">link</a> and then more text.
</div>
现在,让我们假设如果你点了div上除了a链接之外的地方,我们希望能发生点什么事情(比如改变下背景什么的),但是不能影响用户点击a链接的行为(从可用性的角度,这个例子不怎么好,你可能不希望用户点击别的地方时发生任何事情)。
复制代码 代码如下:
$("div.post").click(function () {
// Do the first thing;
});
$("div.post a").click(function (e) {
// Don't cancel the browser's default action
// and don't bubble this event!
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调用放在底部的效果:
复制代码 代码如下: