前言
随着富网络应用(rich web
applications)数量的增长,以及用户对快速交互响应的高期望,开发者开始使用javascript库来快速高效的完成一些重复性的工作。这其
中最流行的javascript库就是jquery。但是jquery的大量应用却带来了另外一个问题:在使用javascript库的时候,有哪些最佳
实践,又有哪些不好的实践呢?
背景
在这篇文章中,我会给大家介绍在编写、调试和审查javascript代码的时候一些好的实践(至少我是这么认为的)。事实上,我选择了其中7个最常见的场景。
1、使用cdn及其回退地址(fallback)
cdn代表内容传递网络(content delivery
network),是一个缓存了javascript文件的服务器。使用cdn之后,每当一个新用户发起请求的时候,你的应用程序可以使用cdn缓存,而
不用从你的服务器上重新加载库文件。google、microsoft和jquery都提供cdn服务。
鉴于网络并不总是100%可靠,服务器也可能因为一些原因宕机,你必须要确保即使这些事情发生,你的应用程序依然能正常运行。这时候我们就要用到回退地址:当应用程序无法找到缓存库的时候,它就会回退回来,使用服务器文件。
google cdn 是这样的:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"> </script>
microsoft cdn是这样的:
<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"> </script>
需要注意的是,我们没有指定url协议为http而是使用的//。这是因为cdn服务器支持http和https,如果你的网站拥有ssl认证,你无须修改就可以正常加载文件。
另外,就像我之前提到的那样,我们还需要一个回退地址,以防cdn服务器出现问题。
<script>window.jquery || document.write(&lsquo;<script src=&rdquo;script/localsourceforjquery&rdquo;></script>&rsquo;)
当然,你也可以用require来配置需要的jquery,不过我觉得就这样也不错。
2、限制dom交互
用javascript操作dom树是存在性能消耗的。jquery也一样。所以,尽量减少与dom的交互吧。当我帮助我一个同事提高数据显示速度的时候,我看见他在一个循环里面使用了选择器。这简直是性能杀手!他是这样写的:
containerdiv = $("#contentdiv");
for(var d =0; d < totalactions; d++)
{
containerdiv.append("<div><span class='brilliantrunner'>" + d + "</span></div>");
}
有什么问题呢?咋一看没啥问题。而且我的同事也说这段代码跑得很欢乐呢!我真是哔了狗了!当totalactions小于50时,察觉不到任何问题;但是其达到25000的时候,速度便降低了很多,原因(我也是google到的)就是dom交互放到了循环当中。
对于这个功能,(多次尝试失败之后)我将循环中的直接dom交互替换成了一个数组的push操作,然后用一个空字符串作为分隔符将数组连接(join)起来。最后,程序当然变得更加流畅和高效了。
var mycontent=[];
for(var d = 0; d < totalactions; d++)
mycontent.push("<div><span class='brilliantrunner'>" + d + "</span></div>");
containerdiv.html(mycontent.join(""));
3、缓存
var $divid = $("#divid")
然后在接下来的代码中,就可以用$divid了。
对于下面的代码:
var thefunction = function()
$("#mydiv").toggleclass("zclass");
$("#mydiv").fadeout(800);
var thefunction2 = function()
$("#mydiv").addattr("name");
$("#mydiv").fadein(400);
我们可以对它做这样的修改,并且使用链式语法,使其看起来更加漂亮:
var mydiv =$("#mydiv");
mydiv.toggleclass("zclass").fadeout(800);
mydiv.addattr("name").fadein(400);
但是话又说回来,你也不用每次把所有东西都缓存起来。看下面的例子:
$("#link").click(function()
$(this).addclass("gored");
在这里,我既没有用 <code>$(“#link”)</code>,或者将其缓存起来,而是使用的<code>$(this)</code>。因为在这个例子中,我操作的对象就是这个链接本身。
4、find 和 filter
最近,在使用find()来获取jquery对象结合的时候,我产生了一些困惑。然后我发现,这个操作可以替换为用filter()方法来实现。理解这两者的区别非常重要:
find: 将会从选定的元素开始,一直向下查找dom树
filter: 是在jquery集合当中查找
5、end()
当在jquery集合中进行链式操作的时候,我有时候需要回到父对象去进行一些操作。比如你正在一个表格的第二行应用css,然后希望回到表格对象,对其添加一些样式。在你对行应用完样式之后,只要使用end()方法,你就会自动回到表格对象,然后随意的对其添加样式吧!
(译者注:find()、filter()和end()原文是大写,其实应该是小写)
6、对象字面量
当你通过链式语法来操作元素的css属性的时候,你可以使用对象字面量方式来提升性能。比如这段代码:
$("#myimg").attr("src", "thepath").attr("alt", "the alt text");
变成下面这样之后,不仅避免了操作dom元素,而且还不用多次调用相关的设置方法:
$("#myimg").attr({"src": "thepath", "alt": "the alt text"});
7、善用css类
尽可能使用css类而不要写内联css代码。我想这一点就不需要举例说明了吧。
最后
我希望这篇文章能够帮助你编写更好的jquery应用程序。
作者:风满楼
来源:51cto