JavaScript编写Web脚本最佳实现

最近在看JavaScript DOM 编程艺术,总结一下用JavaScript编写Web脚本的规范与实现,对于实现有以下几点要求:

  • 平稳退化:确保网页在没有JavaScript下也能正常运行
  • 分离JavaScript:把网页内容与结构与JavaScript行为完全分离
  • 向后兼容:当JavaScript使用新的API时老版本的浏览器正常运行
  • 提升性能:让JavaScript执行的性能最优

平稳退化

JavaScript通过DOM(文本对象模型)来访问HTML页面的各个节点。但是有些网页被浏览器禁用了JavaScript的功能。这就使得JavaScript运行的脚本不能正常工作,此时我们应该确保就算脚本不能工作页面也要正常显示。这样就达到了平稳退化的目的。
对于某些行为比如点击某个链接需要触发某一个操作,此时我们一般通过JavaScript函数与onclick事件绑定来实现:

1
<a href="#" onclick="function_1(`http://www.ggghub.com`); return false;">GGGHub's Blog</a>

如果此时浏览器禁用了JavaScript功能那么这个链接就废掉了,我们想要做到平稳退化只要把代码改写成:

1
<a href="http://www.ggghub.com" onclick="function_1(`http://www.ggghub.com`); return false;">GGGHub's Blog</a>

此时就算JavaScript被禁止了这个链接还是生效的。虽然可能不会达到我们想要的预期但是总比一个这个链接毫无用处强。


分离JavaScript

对于上面写的例子扩展一下,如果此时有多个链接:

1
2
3
4
5
6
7
8
9
10
11
<ul>
<li>
<a href="http://www.ggghub.com" onclick="function_1(`http://www.ggghub.com`); return false;">GGGHub's Blog</a>
</li>
<li>
<a href="http://blog.csdn.net/ggghub" onclick="function_1(`http://blog.csdn.net/ggghub`); return false;">GGGHub's CSDN</a>
</li>
<li>
<a href="https://github.com/ggghub" onclick="function_1(`https://github.com/ggghub`); return false;">GGGHub's GitHub</a>
</li>
</ul>

可以看出来此时在页面里充斥着JavaScript代码。我们虽然知道在HTML中head标签引入js文件但这远远不够。

1
2
3
<head>
<script type="text/javascript" src = "example.js"/>
</head>

这样写虽然把大部分的js代码写在一个单独的文件里,但上面一些事件还绑定着js函数,这样如果我此时想给这些事件更换js的函数或者参数那么就不得不挨个查找和替换。如果跟js相关的都放在单独的文件里那么修改起来就不是很麻烦。需要修改如下:

1
2
3
4
5
6
7
8
9
10
11
<ul>
<li>
<a href="http://www.ggghub.com">GGGHub's Blog</a>
</li>
<li>
<a href="http://blog.csdn.net/ggghub">GGGHub's CSDN</a>
</li>
<li>
<a href="https://github.com/ggghub">GGGHub's GitHub</a>
</li>
</ul>

相关js文件里面的修改

1
2
3
4
5
6
7
8
9
10
window.onload = function (){
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
links[i].onclick = function(){
function_1(this.getAttribute("href"));
return false;
};
links[i].onkeypress = links[i].onclick;
}
}

这样就把JavaScript相关的行为完全从页面中分离了出来。如果此时想要更改相关链接的行为,只要在js文件中修改一处即可。


向后兼容

不同的浏览器对JavaScript支持各不一样,大多数浏览器都支持DOM但是有些老版本的浏览器可能对DOM的支持不是很好所以我们再用JavaScript时要考虑到如果浏览器不支持DOM的某些方法怎么办。
如果考虑向后兼容我们就要判断我们所用的方法可不可以使用。然后如果方法不可用我们再处理不可用的情况。例如我们常用的一些DOM方法

  • getElementsByTagName
  • getElementById
  • getAttribute
  • createElement
  • createTextNode

    实现向后兼容很简单只要依次判断这些方法是否可用
    1
    2
    3
    4
    5
    6
    function example(){
    if (!document.getElementsByTagName) return false;
    if (!document.getElementById) return false;
    if (!document.getAttribute) return false;
    if (!document.createElement) return false;
    }

然后根据返回值来处理当这些方法不可用的情况


提升性能

提升JavaScript对Web的性能应该从下面几个方向去考虑

减少访问DOM减少标记

多次重复通过脚本访问DOM会对性能产生极大的影响例如:

1
2
3
4
5
6
7
8
9
    window.onload = function (){
for (var i = 0; i < document.getElementsByTagName("a").length; i++) {
document.getElementsByTagName("a")[i].onclick = function(){
function_1(this.getAttribute("href"));
return false;
};
document.getElementsByTagName("a")[i].onkeypress = document.getElementsByTagName("a")[i].onclick;
}
}

这样做每次一个循环都要多次搜索整个DOM来获取节点,极大的浪费了性能。最好的做法就是只搜索一次DOM然后把结果放在一个变量里。之后对变量进行操作对于前者极大的提升的性能。
还有一点就是减少标记这样DOM本身规模减少,加快搜索DOM的时间。


合并脚本

对于HTML引用脚本文件可能存在多个脚本文件要一起使用例如

1
2
3
4
<script type="text/javascript" src="example1.js"></script>
<script type="text/javascript" src="example2.js"></script>
<script type="text/javascript" src="example3.js"></script>
<script type="text/javascript" src="example4.js"></script>

这样HTML要多次请求加载js文件。如果把这些文件合并成一个那么只需要请求加载一次即可。
关于script标签放置
script标签有多种放置方法。放在标签中或者标签中

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src=""></script>
</head>
<body>
<script type="text/javascript" src=""></script>
</body>
</html>

如果放在中那么浏览器在加载页面时会先加载js文件,如果js文件加载不出来那么页面其它内容也不会显示。但是如果放在页面最后之前就会优先加载页面。

压缩代码

将代码中不必要的字节去掉,例如空格,注释,换行符等来压缩文件大小,也用专门的工具来进行代码压缩。