jQuery 的常见陷阱






4.85/5 (93投票s)
jQuery 是一个很棒的库,它使使用 JavaScript 进行 Web 开发成为一个更好的体验——但是您应该避免一些常见的陷阱。
引言
如今,jQuery 是事实上的 JavaScript 库。CodeProject 使用 jQuery,Microsoft 使用 jQuery,Google 使用 jQuery,如果您曾经制作过交互式客户端 Web 应用程序,那么您很可能使用 jQuery 来实现它。
这意味着 jQuery 社区非常庞大、活跃且充满活力——这是一件好事。但这也意味着人们经常在没有首先熟悉 Javascript 和 DOM 的情况下开始使用 jQuery 创建东西。当然,jQuery 非常容易上手,即使是新手也可以使用它,这很好。也就是说,人们会使用 jQuery 做一些复杂的事情,而这些事情只需使用 DOM 库、使用稍微晦涩的 jQuery 功能,或者仅仅是更熟悉 Javascript 本身的工作方式就可以简单地完成。
本文的目的是展示人们在使用 jQuery 时遇到的最常见的陷阱。本文假设您知道什么是 jQuery,并且对使用它有一些基本的了解。
过多的 jQuery 调用
不幸的是,经常会看到这样的代码
$("#example").text("Hello, world!");
$("#example").css("color", "red");
$("#example").addClass("fun");
这段代码不必要地昂贵,因为它反复调用 jQuery 来查找与选择器 "#example"
匹配的元素。
有两种替代方法可以做到这一点。首先,您可以缓存查询。
var $example = $("#example");
$example.text("Hello, world!");
$example.css("color", "red");
$example.addClass("fun");
将 jQuery 对象分配给变量时,约定是在变量名前加上美元符号 ($
),以将其标记为 jQuery 对象。
其次,您可以使用 *方法链。* jQuery 方法将返回新的 jQuery 对象,您可以在其上调用更多 jQuery 方法。
$("#example").text("Hello, world!").css("color", "red").addClass("fun");
选择器错误
选择器缺失部分
我在 jQuery 选择器上犯过一个很愚蠢的错误,而且已经浪费了比我愿意承认的更多调试时间。您看到以下示例的问题了吗?
$("example").text("Hello, world!");
很容易错过。如果您没有注意到,选择器中没有井号 (#
) 或点号 (.
) 来指定它正在搜索具有特定 id 的元素或一组具有特定 class 的元素。给定的选择器将查找具有标签名称 example
的元素——这在任何正常情况下都不会存在。
未限定范围的选择器
假设您有一些这样的标记,在大量其他标记中
<!-- lots of HTML here -->
<div id="container">
<div class="box">
</div>
<div class="lid">
</div>
<div class="box">
</div>
<div class="lid">
</div>
<!-- lots of HTML here -->
并且您决定选择所有具有 class box
的 div。所以您只需使用 class 选择器。
$(".box")
这将起作用,但它将 *搜索整个页面* 以查找具有 box
class 的元素。这可能是一个非常昂贵的操作。如果您知道所有具有 box
class 的元素都在 container
div 内部,您可以通过限制搜索边界来加快速度。在 jQuery 中有几种不同的方法可以做到这一点。
$("#container .box")
$("#container").find(".box")
$(".box", $("#container"))
重复选择器
在多个元素选择中使用相同的效果是很常见的。
$("#main").css("color", "red");
$("#content").css("color", "red");
$(".important").css("color", "red");
最好使用逗号 (,
) 选择器来匹配多个选择
$("#main, #content, .important").css("color", "red");
未使用的快捷方式
这些代码行不幸地很常见
$("#el").css("display", "none"); $("#el").css("display", ""); if($("#el").is(":visible")) $("#el").css("display", "none"); else $("#el").css("display", ""); $("#el").html(""); $("#el").prop("class", $("#el").prop("class") + " " + newClass);
当有更快、更易读的快捷方式时
$("#el").hide();
$("#el").show();
$("#el").toggle();
$("#el").empty();
$("#el").addClass(newClass);
不熟悉 DOM
最好 熟悉 DOM,因为有一些事情使用 jQuery 过于冗余。例如,
$('img').click(function() {
alert($(this).attr('src'));
});
当你只需要使用时是多余的
$('img').click(function() {
alert(this.src);
});
类似地,您可以使用 this.id
而不是 $(this).attr("id")
。但是,请小心:某些属性不是标准的,并且不能跨浏览器使用。例如,非标准的 .class
属性将在某些浏览器上起作用,但在其他浏览器上不起作用,但标准的 .className
应该普遍起作用。
AJAX 中的 A 代表异步
您应该利用异步请求。人们常常会对函数没有按照他们期望的顺序执行而感到沮丧,然后禁用异步属性
$.ajax({
async: false
});
禁用 async
会使事情变慢并锁定浏览器,因此这通常不是一个好主意。您应该使用回调来管理您希望事物如何执行。解释回调的工作原理超出了本文的范围,但 有很好的资源 解释了它。
理解动态变化
假设您有此代码,
$("button").click(doSomething);
然后您动态地向页面添加了一些按钮。您会注意到,添加的按钮不会触发 doSomething
函数。这是为什么?click
函数仅将事件绑定到 已经存在 的 button
元素。如果您希望它也绑定到将添加到页面的每个按钮的事件,您需要使用 delegate jQuery 方法
$(document).delegate("button", "click", doSomething);
这将把 doSomething
函数绑定到将永远存在于文档中的每个按钮。如果您只想将其绑定到特定选择器内的按钮,那么您将用您想要的任何选择器替换 document
。
就这些,各位!
这些是我见过并被咬到的最常见的 jQuery 陷阱。如果我遗漏了显而易见的内容,请告诉我,我可能会更新这篇文章。