可能在你剛開(kāi)始學(xué)習(xí)關(guān)于jQuery事件處理時(shí),看到的第一個(gè)例子就是關(guān)于如何阻止瀏覽器執(zhí)行默認(rèn)行為,比如下面這段演示click事件的代碼:
$("a.toggle").click(function () { $("#mydiv").toggle(); return false; // Prevent browser from visiting `#` });
像上面這樣的例子會(huì)讓用戶養(yǎng)成使用“return false”來(lái)阻止瀏覽器執(zhí)行默認(rèn)行為的壞習(xí)慣,在這篇文章里,我將會(huì)討論關(guān)于阻止瀏覽器執(zhí)行默認(rèn)行為的兩個(gè)非常重要的主題:
•選擇正確的方法: return false還是preventDefault,stopPropagation或者stopImmediatePropagation
•選擇合適的位置,開(kāi)始,結(jié)束,還是中間某個(gè)地方:你應(yīng)該在事件回調(diào)的哪個(gè)部分取消瀏覽器執(zhí)行默認(rèn)行為?
注意:當(dāng)我在這篇文章中提到event bubbling(事件冒泡),我想表達(dá)的是大部分事件都是先在初始DOM上觸發(fā),然后再通過(guò)DOM樹(shù)往上,在每一級(jí)父元素上觸發(fā),事件不會(huì)在兄弟節(jié)點(diǎn)或是子節(jié)點(diǎn)上冒泡(當(dāng)事件向下冒泡時(shí),我們叫它事件捕捉(event capturing)),你可以在這里了解更多關(guān)于事件起泡和捕捉的介紹。
選擇正確的方法
“return false”之所以被誤用的如此厲害,是因?yàn)樗雌饋?lái)像是完成了我們交給它的工作,瀏覽器不會(huì)再將我們重定向到href中的鏈接,表單也不會(huì)被繼續(xù)提交,但這么做到底有什么不對(duì)呢?
”return false“到底做了什么?
當(dāng)你每次調(diào)用”return false“的時(shí)候,它實(shí)際上做了3件事情:
•event.preventDefault();
•event.stopPropagation();
•停止回調(diào)函數(shù)執(zhí)行并立即返回。
“等等”,你叫了起來(lái)!我只是想讓瀏覽器停止繼續(xù)執(zhí)行默認(rèn)行為而已,我不需要它去做另外2件事。
這3件事中用來(lái)阻止瀏覽器繼續(xù)執(zhí)行默認(rèn)行為的只有preventDefault,除非你想要停止事件冒泡,否則使用return false會(huì)為你的代碼埋下很大的隱患,讓我們通過(guò)一個(gè)真實(shí)的例子來(lái)看看這樣的誤用會(huì)造成什么后果:
這是我們用來(lái)演示的HTML:
<div class="post"> <h2><a href="http://365jz.com">My Page</a></h2> <div class="content"> Teaser text... </div> </div> <div class="post"> <h2><a href="http://365jz.com">My Other Page</a></h2> <div class="content"> Teaser text... </div> </div>
jQuery(document).ready(function ($) { $("div.post h2 a").click(function () { var a = $(this), href = a.attr('href'), // Let jQuery normalize `href`, content = a.parent().next(); content.load(href + " #content"); return false; // "cancel" the default behavior of following the link }); });
// Inside Document Ready: var posts = $("div.post"); posts.click(function () { // Remove active from all div.post posts.removeClass("active"); // Add it back to this one $(this).addClass("active"); });
如果我們把它和live或者delegate事件混在一起使用時(shí),情況就更糟了。
$("a").click(function () { // do something return false; }); $("a").live("click", function () { // THIS WON'T FIRE });
preventDefault()
大多數(shù)情況下,當(dāng)你使用return false時(shí),你其實(shí)真正需要的是e.preventDefault()。要使用e.preventDefault,你需要確保你傳遞了event參數(shù)到你的回掉函數(shù)中(在這個(gè)例子里,就是那個(gè)e):
$("a").click(function (e) { // e == our event data e.preventDefault(); });
stopPropagation()
但有些情況下,你有可能需要停止事件冒泡,讓我們看看下面的例子:
<div class="post"> Normal text and then a <a href="http://365jz.com">link</a> and then more text. </div>
$("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(); });
stopImmediatePropagation()
這個(gè)方法會(huì)停止一個(gè)事件繼續(xù)執(zhí)行,即使當(dāng)前的對(duì)象上還綁定了其它處理函數(shù),所有綁定在一個(gè)對(duì)象上的事件會(huì)按綁定順序執(zhí)行,看看下面的例子:
$("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 });
return false
只有當(dāng)你同時(shí)需要preventDefault和stopPropagation,并且你的代碼可以接受直到你的回調(diào)執(zhí)行完成才停止執(zhí)行瀏覽器的默認(rèn)行為,那你就可以使用”return false“。但我強(qiáng)烈建議你別在寫(xiě)給其它jQuery開(kāi)發(fā)者的演示代碼中使用這個(gè)方法,因?yàn)檫@會(huì)造成更多誤用,只有在你確信非用不可的情況下再去使用”return false“。
選擇適當(dāng)?shù)奈恢?/strong>
如果你使用了”return false“,它只會(huì)在你的回調(diào)函數(shù)執(zhí)行結(jié)束才去取消瀏覽器的默認(rèn)行為,但是使用e.preventDefault,我們有更多的選擇,它可以隨時(shí)停止瀏覽器執(zhí)行默認(rèn)動(dòng)作,而不管你將它放在函數(shù)的哪個(gè)部分。
1. 開(kāi)發(fā)階段,你應(yīng)該總是將它放在第一行。你最不想做的事情可能就是你正在調(diào)試將一個(gè)form改成ajax提交的時(shí)候,它卻已經(jīng)被按照老方法提交了。
2. 產(chǎn)品階段,如果你采用了漸進(jìn)增強(qiáng)(progressive enhancement),那就把它放到回調(diào)的結(jié)束位置,或者是邏輯終點(diǎn),如果在一個(gè)普通頁(yè)面采用漸進(jìn)增強(qiáng),那你就需要在服務(wù)器端考慮如果瀏覽器不支持JS時(shí)(或者被禁用時(shí)),對(duì)鏈接的click事件和表單的提交事件的處理。這里的好處是,我們不考慮關(guān)閉JS的情況,只考慮支持js時(shí)的強(qiáng)狂,如果你的回調(diào)代碼出錯(cuò)拋出了異常,讓我們看看下面的代碼:
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! });
> 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.在產(chǎn)品階段,如果功能這設(shè)計(jì)JS,那就還應(yīng)該放在第一行。
記住,不必非得是函數(shù)的第一行,但是越早越好,這里的原則是:如果函數(shù)的功能是通過(guò)JS實(shí)現(xiàn)的(不涉及服務(wù)端交互),那就沒(méi)必要考慮兼容,在這種情況下,添加在第一行可以防止URL中出現(xiàn)#字符,但顯然,你還是應(yīng)該盡可能多的增加些錯(cuò)誤處理代碼,以防止用戶在出錯(cuò)時(shí)變得不知所措。
js中return;、return true、return false;區(qū)別
一、返回控制與函數(shù)結(jié)果,
語(yǔ)法為:return 表達(dá)式;
語(yǔ)句結(jié)束函數(shù)執(zhí)行,返回調(diào)用函數(shù),而且把表達(dá)式的值作為函數(shù)的結(jié)果
二、返回控制,
無(wú)函數(shù)結(jié)果,語(yǔ)法為:return;
在大多數(shù)情況下,為事件處理函數(shù)返回false,可以防止默認(rèn)的事件行為.例如,默認(rèn)情況下點(diǎn)擊一個(gè)<a>元素,頁(yè)面會(huì)跳轉(zhuǎn)到該元素href屬性指定的頁(yè).
Return False 就相當(dāng)于終止符,Return True 就相當(dāng)于執(zhí)行符。
在js中return false的作用一般是用來(lái)取消默認(rèn)動(dòng)作的。比如你單擊一個(gè)鏈接除了觸發(fā)你的
onclick時(shí)間(如果你指定的話)以外還要觸發(fā)一個(gè)默認(rèn)事件就是執(zhí)行頁(yè)面的跳轉(zhuǎn)。所以如果
你想取消對(duì)象的默認(rèn)動(dòng)作就可以return false。
首先在js中,我們常用return false來(lái)阻止提交表單或者繼續(xù)執(zhí)行下面的代碼,通俗的來(lái)說(shuō)就是阻止執(zhí)行默認(rèn)的行為。
function a(){
if(True)
return false;
},這是沒(méi)有任何問(wèn)題的。
如果我改成這種
function Test(){
a();
b();
c();
}
即使a函數(shù)返回return false 阻止提交了,但是不影響 b()以及 c()函數(shù)的執(zhí)行。在Test()函數(shù)里調(diào)用a()函數(shù),那面里面
return false 對(duì)于Test()函數(shù)來(lái)說(shuō),只是相當(dāng)于返回值。而不能阻止Test()函數(shù)執(zhí)行。
總之:return false 只在當(dāng)前函數(shù)有效,不會(huì)影響其他外部函數(shù)的執(zhí)行。
三:總結(jié)
retrun true; 返回正確的處理結(jié)果。
return false;分會(huì)錯(cuò)誤的處理結(jié)果,終止處理。
return;把控制權(quán)返回給頁(yè)面。
我希望這篇文章傳達(dá)的信息足夠你在需要阻止瀏覽器執(zhí)行默認(rèn)行為時(shí)做出正確的選擇。記住,只有當(dāng)你真的明白你在做什么時(shí),才使用”return false“,并確保你是在函數(shù)的正確位置調(diào)用了相應(yīng)的代碼。最后,盡可能保持代碼的靈活性,盡量不要再用“return false”了!
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答??! 點(diǎn)擊進(jìn)入論壇