代码改变世界

【小技巧】从多个地方加载同一个JavaScript库,避免加载问题造成内容出错

2010-08-16 08:19  Nana's Lich  阅读(2244)  评论(12编辑  收藏  举报

这个时代几乎没有几个网站不使用JavaScript了——即使的确有些网站提供了无脚本内容,绝大部分RIA还是需要有脚本支持才能使用的。

但是万一脚本在加载的过程中出问题了怎么办?

如果最基本的脚本库没能正常加载,那整个页面就没法看了。

 

对这种加载失败的问题,有一种比较容易使用的方法是判断加载的外部脚本是不是已经正常初始化,如果没有正常初始化则重新加载。

判断的方法一般是这样(以jQuery为例):

if(this.$)
  doSomething(); // 加载成功
else
  doSomethingElse(); // 加载失败

加上重新加载的代码,就可能是这样:

if(!this.$)
  document.write('<script type="text/javascript" src="http://static.my-site.com/script/jquery.js"><\/script>');

看起来挺简单是吧?

但是这里面其实还是有门道的——

首先有一个问题就是,如果一个外部脚本加载出错,未能初始化,那么使用同样的地址再次加载基本上也是要出错的,原因在于:

如果加载外部脚本的时候能获取到内容,但脚本自身存在语法错误,那么在同一个页面中重复请求这个外部脚本时,是会利用缓存中的内容的——也就是说重新加载还是错的;

如果加载外部脚本的时候未能获取任何内容,比方说403、404、500等错误,或者干脆无法连接,那么在短时间内重新请求也不可能获得任何内容,这个措施还等于是废物。

 

所以作为容错措施,不管加载什么脚本,都是要从不同的位置加载的,所以你的容错代码看起来可能会是这样:

<script type="text/javascript" src="http://static.my-site.com/script/jquery.js"></script>
<script type="text/javascript">
if(!this.$)
  document.write('<script type="text/javascript" src="http://static2.my-site.com/script/jquery.js"><\/script>');
</script>

而这个时候 ,又有一个新问题出现了——不管使用什么样的编辑器,作为document.write的参数的内容都是没有HTML语法高亮或者属性面板的,一旦因为某种原因需要修改外部脚本的加载位置的时候,很可能因为没有编辑器的帮助而把容错代码改得一塌糊涂——虽然你可能要说,自己经验丰富,不会犯这种低级错误,但是据我所知很多人就是会把这里弄糟。

所以我对此的建议是,这样做:

<script type="text/javascript" src="http://static.my-site.com/script/jquery.js"></script>
<script type="text/javascript">
this.$ && document.write('<\!--');
</script>
<script type="text/javascript" src="http://static2.my-site.com/script/jquery.js"></script>
<!-- -->

这里利用了JavaScript的一个逻辑运算符技巧,取代了if的作用——当$有效的时候,就输出“<!--”到文档流中,它将会把接下来的内容注释掉,直到遇到“-->”为止;而如果$并不包含一个有效的内容,下边的另一个加载代码就会被执行。

这个技巧使用了尽量少的JavaScript代码,利用纯粹的HTML来进行第二次加载,其可维护性总算是稍微提高了那么一点点。

 

有的时候,你可能并没有第二个服务器用来进行容错加载,但我们这里还是有一些小技巧可以用的,比方说在原来的外部脚本URL后面加上一个半角的问号,甚至再在问号后面加上一些不确定的其它字符——这个小技巧虽然不能解决403、404和500这样的问题,但对网络问题造成的脚本内容加载不完整还是有一些帮助的。

另外,如果你的确使用jQuery作为基础框架的话,你还可以使用微软的AJAX CDN服务。

那么,你的容错代码大概可能是这样:

<script type="text/javascript" src="/script/jquery.js"></script>
<script type="text/javascript">
this.$ && document.write('<\!--');
</script>
<script type="text/javascript" src="/script/jquery.js?2"></script>
<script type="text/javascript">
this.$ && document.write('<\!--');
</script>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
this.$ || alert('哎呀哎呀,这个网页上的脚本完全没法正常加载呢……你说这可如何是好呀?');
</script>
<!-- -->