JavaScript编写Web脚本最佳实现
最近在看JavaScript DOM 编程艺术,总结一下JavaScript编写Web脚本的规范与实现,对于实现有以下几点要求:
- 平稳退化:确保网页在没有
JavaScript下也能正常运行 - 分离
JavaScript:把网页内容与结构与JavaScript行为完全分离 - 向后兼容:当
JavaScript使用新的API时老版本的浏览器正常运行 - 提升性能:让
JavaScript执行的性能最优
平稳退化
JavaScript通过DOM(文本对象模型)来访问HTML页面的各个节点。但是有些网页被浏览器禁用了JavaScript的功能。这就使得JavaScript运行的脚本不能正常工作,此时我们应该确保就算脚本不能工作页面也要正常显示。这样就达到了平稳退化的目的。
对于某些行为比如点击某个链接需要触发某一个操作,此时我们一般通过JavaScript函数与onclick事件绑定来实现:
<a href="#" onclick="function_1(`http://www.ggghub.com`); return false;">GGGHub's Blog</a>
如果此时浏览器禁用了JavaScript功能那么这个链接就废掉了,我们想要做到平稳退化只要把代码改写成:
<a href="http://www.ggghub.com" onclick="function_1(`http://www.ggghub.com`); return false;">GGGHub's Blog</a>
此时就算JavaScript被禁止了这个链接还是生效的。虽然可能不会达到我们想要的预期但是总比一个这个链接毫无用处强。
分离JavaScript
对于上面写的例子扩展一下,如果此时有多个链接:
<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文件但这远远不够。
<head>
<script type="text/javascript" src = "example.js" />
</head>
这样写虽然把大部分的js代码写在一个单独的文件里,但上面一些事件还绑定着js函数,这样如果我此时想给这些事件更换js的函数或者参数那么就不得不挨个查找和替换。如果跟js相关的都放在单独的文件里那么修改起来就不是很麻烦。需要修改如下:
<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文件里面的修改
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
…
实现向后兼容很简单只要依次判断这些方法是否可用
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会对性能产生极大的影响例如:
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引用脚本文件可能存在多个脚本文件要一起使用例如
<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标签有多种放置方法。放在标签中或者标签中
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src=""></script>
</head>
<body>
<script type="text/javascript" src=""></script>
</body>
</html>
如果放在中那么浏览器在加载页面时会先加载js文件,如果js文件加载不出来那么页面其它内容也不会显示。但是如果放在页面最后之前就会优先加载页面。
压缩代码
将代码中不必要的字节去掉,例如空格,注释,换行符等来压缩文件大小,也用专门的工具来进行代码压缩。
JavaScript编写Web脚本最佳实现的更多相关文章
- ECMAScript进化史(1):话说Web脚本语言王者JavaScript的加冕历史
互联网起火-Web时代的来临 在行文之前,反手就安利一下<浏览器史话中chrome霸主地位的奠定与国产浏览器的割据混战>. 浏览器始祖NCSA Mosaic在1993年1月发布(于1992 ...
- SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。
熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...
- 编写Shell脚本的最佳实践
编写Shell脚本的最佳实践 http://kb.cnblogs.com/page/574767/ 需要记住的 代码有注释 #!/bin/bash # Written by steven # Name ...
- 4.3.6 对象的界定通过编写接口来访问带这类命名结构的表会出问题。如前所述,SQL Server的灵活性不应用作编写错误代码或创建问题对象的借口。 注意在使用Management Studio的脚本工具时,SQL Server会界定所有的对象。这不是因为这么做是必须的,也不是编写代码的最佳方式,而是因为在界定符中封装所有的对象,比编写脚本引擎来查找需要界定的对象更容易。
如前所述,在创建对象时,最好避免使用内嵌的空格或保留字作为对象名,但设计人员可能并没有遵守这个最佳实践原则.例如,我当前使用的数据库中有一个审核表名为Transaction,但是Transaction ...
- JavaScript Web 应用最佳实践分析
[编者按]本文作者为 Mathias Schäfer,旨在回顾在客户端大量使用JavaScript 的最佳 Web应用实践.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 对笔者来说,Jav ...
- Selenium(十七):unittest单元测试框架(三) 脚本分析、编写Web用例
1. 带unittest的脚本分析 也许你现在心里还有疑问,unittest框架与我们前面所编写的Web自动化测试之间有什么必然联系吗?当然有,既然unittest可以组织.运行测试用例,那么为什么不 ...
- 《Professional JavaScript for Web Developers》day02
<Professional JavaScript for Web Developers>day02 1.在HTML中使用JavaScript 1.1 <script>元素 HT ...
- When Colon Scripting is comming (脚本最佳体验)
当冒号脚本来临-- 脚本最佳体验 冒号指派 说明; 冒号替代等号指派赋值,当命名声明指派时指定.相当于声明当前作用域的一个名字指派. 当对指定对象的属性赋值时候,依旧请使用等号.即不废弃等号赋值功用, ...
- 学习 Linux,101: 自定义或编写简单脚本【转】
转自:http://www.ibm.com/developerworks/cn/linux/l-lpic1-105-2/index.html 学习如何使用标准的 shell 语法.循环和控制结构,以及 ...
随机推荐
- BZOJ 3126 [USACO2013 Open]Photo (单调队列优化DP)
洛谷传送门 题目大意:给你一个长度为$n$的序列和$m$个区间,每个区间内有且仅有一个1,其它数必须是0,求整个序列中数字1最多的数量 神题,竟然是$DP$ 定义$f_{i}$表示第i位放一个1时,最 ...
- frp(升级版)教程
注:之前的教程是按照官网文档亲自实践操作汇总而成的,所需的软件也是从官网下载的. 但是有一个问题,若是运行在有公网IP的frps程序被其他人所知道,他们就可以直接在他们电脑上运行frpc客户端, 简而 ...
- 设置PATH 环境变量、pyw格式、命令行运行python程序与多重剪贴板
pyw格式简介: 与py类似,我认为他们俩卫衣的不同就是前者运行时候不显示终端窗口,后者显示 命令行运行python程序: 在我学习python的过程中我通常使用IDLE来运行程序,这一步骤太过繁琐( ...
- python_for循环
#for循环'''for i in range(0,10,2):age_oldboy = 56for i in range(3): guess_age = int(input("guess ...
- [LeetCode] 350. 两个数组的交集 II intersection-of-two-arrays-ii(排序)
思路: 先找到set的交集,然后分别计算交集中的每个元素在两个原始数组中出现的最小次数. class Solution(object): def intersect(self, nums1, nums ...
- 小学生绞尽脑汁也学不会的python(反射)
小学生绞尽脑汁也学不会的python(反射) 1. issubclass, type, isinstance issubclass 判断xxxx类是否是xxxx类的子类 type 给出xxx的数据类型 ...
- Vue生命周期函数的应用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SQL SERVER-常用命令2
1.创建新表 create table mytest ( id int primary key identity(1,1),--主键,自动+1 name varchar(20) unique notn ...
- linux 数据库
查看数据库状态:service mysqld status 启动数据库服务 service mysql start 如果出现:Another MySQL daemon already running ...
- bzoj3295: [Cqoi2011]动态逆序对(cdq分治+树状数组)
3295: [Cqoi2011]动态逆序对 题目:传送门 题解: 刚学完cdq分治,想起来之前有一道是树套树的题目可以用cdq分治来做...尝试一波 还是太弱了...想到了要做两次cdq...然后伏地 ...