关于别再乱用JQ return false

本文详细解析JavaScript事件处理中的event.preventDefault()与returnfalse的区别,包括它们各自的功能、适用场景及如何正确使用以避免潜在的问题。

event.preventDefault()方法是用于取消事件的默认行为,但此方法并不被ie支持,在ie下需要用window.event.returnValue = false; 来实现。


这不是JQuery的方法,是JS本身自带的

event.preventDefault()
该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)。例如,如果 type 属性是 "submit",在事件传播的任意阶段可以调用任意的事件句柄,通过调用该方法,可以阻止提交表单。注意,如果 Event 对象的 cancelable 属性是 fasle,那么就没有默认动作,或者不能阻止默认动作。无论哪种情况,调用该方法都没有作用。

event.stopPropagation()
该方法将停止事件的传播,阻止它被分派到其他 Document 节点。在事件传播的任何阶段都可以调用它。注意,虽然该方法不能阻止同一个 Document 节点上的其他事件句柄被调用,但是它可以阻止把事件分派到其他节点。

event是DOM的事件方法,所以不是单独使用,比如指定DOM



在jQuery代码中,我们常见用return false来阻止浏览器的默认行为。例如点击链接,浏览器默认打开一个新窗口/标签,为了阻止浏览器的默认行为,我们往往这样操作:

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

这段代码的作用是通过点击toggle来隐藏或显示#mydiv,并阻止浏览器继续访问href指定链接。测试如下:

click toggle
点击上一行的toggle,这段文字将被显示或隐藏。

return false达到了我们想要的目的,但这并不是阻止浏览器执行默认行为的正确方法。调用return false,它实际完成了3件事:

  1. event.preventDefault()
  2. event.stopPropagation()
  3. 停止回调函数执行并立即返回。

我们真正的目的是event.preventDefault(),后两者可不是我们想要的。JavaScript事件有两种,一种称为事件冒泡(event bubbling),一种称为事件捕捉(event capturing)。事件冒泡指事件在初始DOM上触发,通过DOM树往上在每一级父元素上触发;当事件向下冒泡时,我们则称之为事件捕获。

因为return false多做了两件事,由此为代码埋下隐患。下面有一个简单的例子,点击一个链接,加载新的页面内容到当前页面:

<div class="post">
    <a href="/js/loadp1.txt">Click here to load page1</a>
    <div class="content">
    </div>
</div>

<div class="post">
    <a href="/js/loadp2.txt">Click here to load page2</a>
    <div class="content">
    </div>
</div>

$("div.post a").click(function() {
    var href = $(this).attr("href");
    $(this).next().load(href);
    return false;
});

测试如下:

点击链接就能加载页面内容到当前页,一切都OK。现在我们想要加一个新功能,例如论坛帖子的浏览,只有当前点击的帖子内容才会显示,其他帖子都隐藏。为此我们需要为div.post加一个click()事件处理:

$("div.post").click(function(){
    $("div.post .content").hide();          // hide all content
    $(this).children(".content").show();    // show this one
});

添加完这段代码后,我们发现它不生效,缘故是因为$("div.post a").click(function() { return false; });,由于return false执行了event.stopPropagation(),因此事件不能冒泡到上一级DOM,即$("div.post").click()不会被事件触发。要达成我们的任务,应该把return false替换为event.preventDefault():

$("div.post a").click(function(e) {
    var href = $(this).attr("href");
    $(this).next().load(href);
    e.preventDefault();
});

测试修改后的代码:

如果把return false和live/delegate事件混用,情况就更糟糕了:

$("a").click(function(){
    // do something
    return false;
});

$("a").live("click", function(){
    // this won't fire
});

如果确实需要阻止事件冒泡,也应该显式地调用:

$("div.post").click(function(){
    // do something
});
$("div.post a").click(function(e){
    // 浏览器跳转到新页面(默认行为)
    // 但阻止事件冒泡,即不会执行$("div.post").click()
    e.stopPropagation();
});

event.stopPropagation()用于阻止事件冒泡,jQuery中还有另一个函数:event.stopImmediatePropagation(),它用于阻止一个事件的继续执行,即使当前对象上还绑定了其他处理函数:

$("div a").click(function(){
    // do something
});

$("div a").click(function(e){
    // stop immediate propagation
    e.stopImmediatePropagation();
});

$("div a").click(function(){
    // never fires
});

$("div a").click(function(){
    // never fires
});

最后结论是:理解return false,尽量避免使用它,请用event.preventDefault()替代return false。


能否别乱添加功能,我的PoiSearch就这些:// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package com.amap.api.services.poisearch; import android.content.Context; import com.amap.api.col.3nsl.jq; import com.amap.api.col.3nsl.lr; import com.amap.api.services.core.AMapException; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.core.PoiItem; import com.amap.api.services.interfaces.IPoiSearch; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; /** @deprecated */ public class PoiSearch { public static final String ENGLISH = "en"; public static final String CHINESE = "zh-CN"; public static final String EXTENSIONS_ALL = "all"; public static final String EXTENSIONS_BASE = "base"; private IPoiSearch a = null; public PoiSearch(Context var1, Query var2) throws AMapException { if (this.a == null) { try { this.a = new lr(var1, var2); return; } catch (Exception var3) { var3.printStackTrace(); if (var3 instanceof AMapException) { throw (AMapException)var3; } } } } public void setOnPoiSearchListener(OnPoiSearchListener var1) { if (this.a != null) { this.a.setOnPoiSearchListener(var1); } } /** @deprecated */ public void setLanguage(String var1) { if (this.a != null) { this.a.setLanguage(var1); } } /** @deprecated */ public String getLanguage() { return this.a != null ? this.a.getLanguage() : null; } public PoiResult searchPOI() throws AMapException { return this.a != null ? this.a.searchPOI() : null; } public void searchPOIAsyn() { if (this.a != null) { this.a.searchPOIAsyn(); } } public PoiItem searchPOIId(String var1) throws AMapException { return this.a != null ? this.a.searchPOIId(var1) : null; } public void searchPOIIdAsyn(String var1) { if (this.a != null) { this.a.searchPOIIdAsyn(var1); } } public void setQuery(Query var1) { if (this.a != null) { this.a.setQuery(var1); } } public void setBound(SearchBound var1) { if (this.a != null) { this.a.setBound(var1); } } public Query getQuery() { return this.a != null ? this.a.getQuery() : null; } public SearchBound getBound() { return this.a != null ? this.a.getBound() : null; } private static boolean b(String var0, String var1) { if (var0 == null && var1 == null) { return true; } else { return var0 != null && var1 != null ? var0.equals(var1) : false; } } public static class Query implements Cloneable { private String a; private String b; private String c; private int d; private int e; private String f; private boolean g; private boolean h; private String i; private boolean j; private LatLonPoint k; private boolean l; private Map<String, String> m; private String n; public Query(String var1, String var2) { this(var1, var2, (String)null); } public Query(String var1, String var2, String var3) { this.d = 1; this.e = 20; this.f = "zh-CN"; this.g = false; this.h = false; this.j = true; this.l = true; this.m = new HashMap(); this.n = "base"; this.a = var1; this.b = var2; this.c = var3; } public String getBuilding() { return this.i; } public void setBuilding(String var1) { this.i = var1; } public String getQueryString() { return this.a; } /** @deprecated */ public void setQueryLanguage(String var1) { if ("en".equals(var1)) { this.f = "en"; } else { this.f = "zh-CN"; } } protected String getQueryLanguage() { return this.f; } public String getCategory() { return this.b != null && !this.b.equals("00") && !this.b.equals("00|") ? this.b : a(); } private static String a() { return ""; } public String getCity() { return this.c; } public int getPageNum() { return this.d; } public void setPageNum(int var1) { if (var1 <= 0) { var1 = 1; } this.d = var1; } public void setPageSize(int var1) { if (var1 <= 0) { this.e = 20; } else if (var1 > 30) { this.e = 30; } else { this.e = var1; } } public int getPageSize() { return this.e; } public void setCityLimit(boolean var1) { this.g = var1; } public boolean getCityLimit() { return this.g; } public void requireSubPois(boolean var1) { this.h = var1; } public boolean isRequireSubPois() { return this.h; } public boolean isDistanceSort() { return this.j; } public void setDistanceSort(boolean var1) { this.j = var1; } public LatLonPoint getLocation() { return this.k; } public void setLocation(LatLonPoint var1) { this.k = var1; } public boolean isSpecial() { return this.l; } public void setSpecial(boolean var1) { this.l = var1; } public String getExtensions() { return this.n; } public void setExtensions(String var1) { this.n = var1; } public void setCustomParams(Map<String, String> var1) { if (var1 != null) { this.m.putAll(var1); } } public Map<String, String> getCustomParams() { return this.m; } public boolean queryEquals(Query var1) { if (var1 == null) { return false; } else if (var1 == this) { return true; } else { return PoiSearch.b(var1.a, this.a) && PoiSearch.b(var1.b, this.b) && PoiSearch.b(var1.f, this.f) && PoiSearch.b(var1.c, this.c) && PoiSearch.b(var1.n, this.n) && PoiSearch.b(var1.i, this.i) && var1.g == this.g && var1.e == this.e && var1.j == this.j && var1.m.equals(this.m) && var1.l == this.l; } } public int hashCode() { int var1 = this.a != null ? this.a.hashCode() : 0; var1 = 31 * var1 + (this.b != null ? this.b.hashCode() : 0); var1 = 31 * var1 + (this.c != null ? this.c.hashCode() : 0); var1 = 31 * var1 + this.d; var1 = 31 * var1 + this.e; var1 = 31 * var1 + (this.f != null ? this.f.hashCode() : 0); var1 = 31 * var1 + (this.g ? 1 : 0); var1 = 31 * var1 + (this.h ? 1 : 0); var1 = 31 * var1 + (this.i != null ? this.i.hashCode() : 0); var1 = 31 * var1 + (this.j ? 1 : 0); var1 = 31 * var1 + (this.k != null ? this.k.hashCode() : 0); var1 = 31 * var1 + (this.l ? 1 : 0); var1 = 31 * var1 + (this.m != null ? this.m.hashCode() : 0); return 31 * var1 + (this.n != null ? this.n.hashCode() : 0); } public boolean equals(Object var1) { if (this == var1) { return true; } else if (var1 != null && this.getClass() == var1.getClass()) { var1 = var1; if (this.d != var1.d) { return false; } else if (this.e != var1.e) { return false; } else if (this.g != var1.g) { return false; } else if (this.h != var1.h) { return false; } else if (this.j != var1.j) { return false; } else if (this.l != var1.l) { return false; } else if (!Objects.equals(this.a, var1.a)) { return false; } else if (!Objects.equals(this.b, var1.b)) { return false; } else if (!Objects.equals(this.c, var1.c)) { return false; } else if (!Objects.equals(this.f, var1.f)) { return false; } else if (!Objects.equals(this.i, var1.i)) { return false; } else if (!Objects.equals(this.k, var1.k)) { return false; } else { return !Objects.equals(this.m, var1.m) ? false : Objects.equals(this.n, var1.n); } } else { return false; } } public Query clone() { try { super.clone(); } catch (CloneNotSupportedException var2) { jq.a(var2, "PoiSearch", "queryclone"); } Query var1; (var1 = new Query(this.a, this.b, this.c)).setPageNum(this.d); var1.setPageSize(this.e); var1.setQueryLanguage(this.f); var1.setCityLimit(this.g); var1.requireSubPois(this.h); var1.setBuilding(this.i); var1.setLocation(this.k); var1.setDistanceSort(this.j); var1.setSpecial(this.l); var1.setExtensions(this.n); var1.setCustomParams(this.m); return var1; } } public static class SearchBound implements Cloneable { private LatLonPoint a; private LatLonPoint b; private int c = 1500; private LatLonPoint d; private String e; private boolean f = true; private List<LatLonPoint> g; public static final String BOUND_SHAPE = "Bound"; public static final String POLYGON_SHAPE = "Polygon"; public static final String RECTANGLE_SHAPE = "Rectangle"; public static final String ELLIPSE_SHAPE = "Ellipse"; public SearchBound(LatLonPoint var1, int var2) { this.e = "Bound"; this.c = var2; this.d = var1; } public SearchBound(LatLonPoint var1, int var2, boolean var3) { this.e = "Bound"; this.c = var2; this.d = var1; this.f = var3; } public SearchBound(LatLonPoint var1, LatLonPoint var2) { this.e = "Rectangle"; this.a(var1, var2); } public SearchBound(List<LatLonPoint> var1) { this.e = "Polygon"; this.g = var1; } private SearchBound(LatLonPoint var1, LatLonPoint var2, int var3, LatLonPoint var4, String var5, List<LatLonPoint> var6, boolean var7) { this.a = var1; this.b = var2; this.c = var3; this.d = var4; this.e = var5; this.g = var6; this.f = var7; } private void a(LatLonPoint var1, LatLonPoint var2) { this.a = var1; this.b = var2; if (this.a.getLatitude() >= this.b.getLatitude() || this.a.getLongitude() >= this.b.getLongitude()) { (new IllegalArgumentException("invalid rect ")).printStackTrace(); } this.d = new LatLonPoint((this.a.getLatitude() + this.b.getLatitude()) / (double)2.0F, (this.a.getLongitude() + this.b.getLongitude()) / (double)2.0F); } public LatLonPoint getLowerLeft() { return this.a; } public LatLonPoint getUpperRight() { return this.b; } public LatLonPoint getCenter() { return this.d; } public int getRange() { return this.c; } public String getShape() { return this.e; } public boolean isDistanceSort() { return this.f; } public List<LatLonPoint> getPolyGonList() { return this.g; } public int hashCode() { int var1 = 31 + (this.d == null ? 0 : this.d.hashCode()); var1 = 31 * var1 + (this.f ? 1231 : 1237); var1 = 31 * var1 + (this.a == null ? 0 : this.a.hashCode()); var1 = 31 * var1 + (this.b == null ? 0 : this.b.hashCode()); var1 = 31 * var1 + (this.g == null ? 0 : this.g.hashCode()); var1 = 31 * var1 + this.c; return 31 * var1 + (this.e == null ? 0 : this.e.hashCode()); } public boolean equals(Object var1) { if (this == var1) { return true; } else if (var1 == null) { return false; } else if (this.getClass() != var1.getClass()) { return false; } else { var1 = var1; if (this.d == null) { if (var1.d != null) { return false; } } else if (!this.d.equals(var1.d)) { return false; } if (this.f != var1.f) { return false; } else { if (this.a == null) { if (var1.a != null) { return false; } } else if (!this.a.equals(var1.a)) { return false; } if (this.b == null) { if (var1.b != null) { return false; } } else if (!this.b.equals(var1.b)) { return false; } if (this.g == null) { if (var1.g != null) { return false; } } else if (!this.g.equals(var1.g)) { return false; } if (this.c != var1.c) { return false; } else { if (this.e == null) { if (var1.e != null) { return false; } } else if (!this.e.equals(var1.e)) { return false; } return true; } } } } public SearchBound clone() { try { super.clone(); } catch (CloneNotSupportedException var1) { jq.a(var1, "PoiSearch", "SearchBoundClone"); } return new SearchBound(this.a, this.b, this.c, this.d, this.e, this.g, this.f); } } public interface OnPoiSearchListener { void onPoiSearched(PoiResult var1, int var2); void onPoiItemSearched(PoiItem var1, int var2); } } PoiItem就这些:// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package com.amap.api.services.core; import android.os.Parcel; import android.os.Parcelable; import com.amap.api.services.poisearch.IndoorData; import com.amap.api.services.poisearch.Photo; import com.amap.api.services.poisearch.PoiItemExtension; import com.amap.api.services.poisearch.SubPoiItem; import java.util.ArrayList; import java.util.List; public class PoiItem implements Parcelable { private String a; private String b; private String c; private String d; private String e = ""; private int f = -1; private final LatLonPoint g; private final String h; private final String i; private LatLonPoint j; private LatLonPoint k; private String l; private String m; private String n; private String o; private String p; private String q; private String r; private boolean s; private IndoorData t; private String u; private String v; private String w; private List<SubPoiItem> x = new ArrayList(); private List<Photo> y = new ArrayList(); private PoiItemExtension z; private String A; private String B; public static final Parcelable.Creator<PoiItem> CREATOR = new Parcelable.Creator<PoiItem>() { private static PoiItem a(Parcel var0) { return new PoiItem(var0); } private static PoiItem[] a(int var0) { return new PoiItem[var0]; } }; public PoiItem(String var1, LatLonPoint var2, String var3, String var4) { this.a = var1; this.g = var2; this.h = var3; this.i = var4; } public String getBusinessArea() { return this.v; } public void setBusinessArea(String var1) { this.v = var1; } public String getAdName() { return this.r; } public void setAdName(String var1) { this.r = var1; } public String getCityName() { return this.q; } public void setCityName(String var1) { this.q = var1; } public String getProvinceName() { return this.p; } public void setProvinceName(String var1) { this.p = var1; } public String getTypeDes() { return this.e; } public void setTypeDes(String var1) { this.e = var1; } public String getTel() { return this.b; } public void setTel(String var1) { this.b = var1; } public String getAdCode() { return this.c; } public void setAdCode(String var1) { this.c = var1; } public String getPoiId() { return this.a; } public int getDistance() { return this.f; } public void setDistance(int var1) { this.f = var1; } public String getTitle() { return this.h; } public String getSnippet() { return this.i; } public LatLonPoint getLatLonPoint() { return this.g; } public String getCityCode() { return this.d; } public void setCityCode(String var1) { this.d = var1; } public LatLonPoint getEnter() { return this.j; } public void setEnter(LatLonPoint var1) { this.j = var1; } public LatLonPoint getExit() { return this.k; } public void setExit(LatLonPoint var1) { this.k = var1; } public String getWebsite() { return this.l; } public void setWebsite(String var1) { this.l = var1; } public String getPostcode() { return this.m; } public void setPostcode(String var1) { this.m = var1; } public String getEmail() { return this.n; } public void setEmail(String var1) { this.n = var1; } public String getDirection() { return this.o; } public void setDirection(String var1) { this.o = var1; } public void setIndoorMap(boolean var1) { this.s = var1; } public boolean isIndoorMap() { return this.s; } public void setProvinceCode(String var1) { this.u = var1; } public String getProvinceCode() { return this.u; } public void setParkingType(String var1) { this.w = var1; } public String getParkingType() { return this.w; } public void setSubPois(List<SubPoiItem> var1) { this.x = var1; } public List<SubPoiItem> getSubPois() { return this.x; } public IndoorData getIndoorData() { return this.t; } public void setIndoorDate(IndoorData var1) { this.t = var1; } public List<Photo> getPhotos() { return this.y; } public void setPhotos(List<Photo> var1) { this.y = var1; } public PoiItemExtension getPoiExtension() { return this.z; } public void setPoiExtension(PoiItemExtension var1) { this.z = var1; } public String getTypeCode() { return this.A; } public void setTypeCode(String var1) { this.A = var1; } public String getShopID() { return this.B; } public void setShopID(String var1) { this.B = var1; } protected PoiItem(Parcel var1) { this.a = var1.readString(); this.c = var1.readString(); this.b = var1.readString(); this.e = var1.readString(); this.f = var1.readInt(); this.g = (LatLonPoint)var1.readValue(LatLonPoint.class.getClassLoader()); this.h = var1.readString(); this.i = var1.readString(); this.d = var1.readString(); this.j = (LatLonPoint)var1.readValue(LatLonPoint.class.getClassLoader()); this.k = (LatLonPoint)var1.readValue(LatLonPoint.class.getClassLoader()); this.l = var1.readString(); this.m = var1.readString(); this.n = var1.readString(); boolean[] var2 = new boolean[1]; var1.readBooleanArray(var2); this.s = var2[0]; this.o = var1.readString(); this.p = var1.readString(); this.q = var1.readString(); this.r = var1.readString(); this.u = var1.readString(); this.v = var1.readString(); this.w = var1.readString(); this.x = var1.readArrayList(SubPoiItem.class.getClassLoader()); this.t = (IndoorData)var1.readValue(IndoorData.class.getClassLoader()); this.y = var1.createTypedArrayList(Photo.CREATOR); this.z = (PoiItemExtension)var1.readParcelable(PoiItemExtension.class.getClassLoader()); this.A = var1.readString(); this.B = var1.readString(); } public int describeContents() { return 0; } public void writeToParcel(Parcel var1, int var2) { var1.writeString(this.a); var1.writeString(this.c); var1.writeString(this.b); var1.writeString(this.e); var1.writeInt(this.f); var1.writeValue(this.g); var1.writeString(this.h); var1.writeString(this.i); var1.writeString(this.d); var1.writeValue(this.j); var1.writeValue(this.k); var1.writeString(this.l); var1.writeString(this.m); var1.writeString(this.n); var1.writeBooleanArray(new boolean[]{this.s}); var1.writeString(this.o); var1.writeString(this.p); var1.writeString(this.q); var1.writeString(this.r); var1.writeString(this.u); var1.writeString(this.v); var1.writeString(this.w); var1.writeList(this.x); var1.writeValue(this.t); var1.writeTypedList(this.y); var1.writeParcelable(this.z, var2); var1.writeString(this.A); var1.writeString(this.B); } public boolean equals(Object var1) { if (this == var1) { return true; } else if (var1 == null) { return false; } else if (this.getClass() != var1.getClass()) { return false; } else { var1 = var1; if (this.a == null) { if (var1.a != null) { return false; } } else if (!this.a.equals(var1.a)) { return false; } return true; } } public int hashCode() { return 31 + (this.a == null ? 0 : this.a.hashCode()); } public String toString() { return this.h; } } PoiResult就这些:// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package com.amap.api.services.poisearch; import com.amap.api.services.core.PoiItem; import com.amap.api.services.core.SuggestionCity; import java.util.ArrayList; import java.util.List; public final class PoiResult { private int a; private ArrayList<PoiItem> b = new ArrayList(); private PoiSearch.Query c; private PoiSearch.SearchBound d; private List<String> e; private List<SuggestionCity> f; private int g; public static PoiResult createPagedResult(PoiSearch.Query var0, PoiSearch.SearchBound var1, List<String> var2, List<SuggestionCity> var3, int var4, int var5, ArrayList<PoiItem> var6) { return new PoiResult(var0, var1, var2, var3, var4, var5, var6); } private PoiResult(PoiSearch.Query var1, PoiSearch.SearchBound var2, List<String> var3, List<SuggestionCity> var4, int var5, int var6, ArrayList<PoiItem> var7) { this.c = var1; this.d = var2; this.e = var3; this.f = var4; this.g = var5; this.a = this.a(var6); this.b = var7; } public final int getPageCount() { return this.a; } public final PoiSearch.Query getQuery() { return this.c; } public final PoiSearch.SearchBound getBound() { return this.d; } public final ArrayList<PoiItem> getPois() { return this.b; } public final List<String> getSearchSuggestionKeywords() { return this.e; } public final List<SuggestionCity> getSearchSuggestionCitys() { return this.f; } private int a(int var1) { return (var1 + this.g - 1) / this.g; } }
最新发布
12-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值