- 页面调用规则:
- 原则上整个网站都用到的JS代码,放到配置文件里,统一命名为commons.js / aisncommons.js 等等。
- 原则上只有某个Channel用到的JS文件,放在该Channel里的layout上引用,用Channel名来命名。不要放到全网站(比如minisite, join flow等等)。
- 原则上只有当前单个页面用到的JS, 就写在页面里,不要单独新建JS文件。如果该JS影响到SEO,则新建JS文件。
- 原则上JS不输出内容,仅控制页面行为。(例如JS可进行check box的select all操作,但是不允许输出check box的内容)
- 兼容性规则:
提倡开发人员以兼容所有浏览器为荣,在确实无法实现的情况下,再考虑以下兼容表(以下说的 "x%的浏览器" 指有x%的PV由该浏览器产生),该数据每三月取一次,定期更新。
兼容度浏览器备注
完全兼容IE 6、 FF1.5 IE7
必须支持主功能,查看重要信息,允许辅助功能不可用。FF 1.0、Safari例如必须保证search、feed back、注册、post product等主要功能可用,但是如My Recent History等允许不可用。
可查看网站重要信息1%以下, 或客户端禁用JS、设置高安全级别等不做兼容调试 - 命名规则(以工程师手册为基准):
- 一般原则:
- 简单明确,见名知意,统一规范。使用较短的英文单词全称,不使用首字母或则缩写,除非缩写被广泛应用,如HTML、URL。
- 使用正确的英文单词和语法。
- 即使是随机访问者也能明白其用意。
- 变量、方法(类)名:
- 采用每个内部单词首字母大写,其余字母小写的格式。例如:strUserName
- 临时数字变量i j k m n ,字符串变量c d e
- 常量以及全局变量名必须全部使用大写字母 。
- 变量名必须使用其类型的所写字符串开始。各种类型的所写字符串如下:
- 数字变量:i //js不允许显式声明int, 数字以Number这个对象来管理, 因此所有数字都用i做前缀
- 对象引用变量:o //object
- HTML DOM 变量:d //document
- 字符串变量:s //string
- 数组变量:a //array
- Date类型变量:dtm
- 变量名必须采用有意义的单词命名,如:
sUserName、iUserAge - 如果变量名过长可以使用单词缩写,除了被广泛了解的单词缩写以外,所有使用单词所写的变量名必须在定义时给出注释,如:
var sAdName //用于表示Administrator帐户的名称
var sAdminName //不用给出注释,Admin被广泛了解
- 变量使用规范
- 变量使用前必须定义。没有定义的变量禁止使用
- 变量的使用尽量缩小到小的作用域。如循环使用 //这点很重要
for(var i=0;i<12;i++){ } 而不是: var i; for(i=0;i<12,i++){ }
- 对象命名规范 如果在代码中,需要强调对象的类型,参考本命名规则
各种页面对象如text输入框、按钮、下拉选择框在命名时必须使用以下对应前缀:- text输入框:txt
- button按钮:btn
- select下拉选择框:sel
- option项:opt
- form表单:frm
- frame框架:fra
- hidden表单项:hdn
- div标记:div
- span标记:span
- 对话框对象:dlg
- 窗口对象:win
- 函数以及子过程命名规范
- 函数命名必须使用动词+名词对的方式,并且能够体现函数的功能
- 函数命名的动词前缀必须是同函数功能相关的完整动词
- 函数命名第一个单词的首字母小写,后面每一个单词的首字母大写
- 文件命名:
- 字母全部采用小写,单词之间用下划线"_"分隔
- 采用"频道名+模块",例如minisite_menu.js。如果全站使用,则采用模块名,如menu.js
- 一般原则:
- 其他规则
- 必须按照标准来写触发事件,比如onClick等,需注意大小写。建议关闭UE中的自动修改功能。
- 原则上不允许写死循环,看起来很可笑的规则,但是在写JS程序时常会碰到,因为在JS中常使用死循环来创造实时更新的效果。
- 在调用的JS文件中,除了变量申明外,不允许有执行部分,必须在HTML中触发或者调用。直接写在HTML代码中或者单个页面使用的JS不在此列。
- 使用JS前请综合考虑HTML、CSS、JS、后台程序之间的最优配合,尽量以HTML、CSS配合来实现效果。
- JS中应当考虑更多的效率问题,因为他的运行环境很差。也许他跑在p2 200, 64M的机器上,用户还开了N个页面。
- js中escape方法对某些字符不作encode,如"+"
- JS开发经验
以下以 IE 代替 Internet Explorer,以 MF 代替 Mozzila Firefox- document.form.item 问题
- 现有问题:
现有代码中存在许多 document.formName.item("itemName") 这样的语句,不能在 MF 下运行 - 解决方法:
改用 document.formName.elements[softwaretech:"elementName"]
- 现有问题:
- 集合类对象问题
- 现有问题:
现有代码中许多集合类对象取用时使用 (),IE 能接受,MF 不能。 - 解决方法:
改用 [] 作为下标运算。如:document.forms("formName") 改为 document.forms[softwaretech:"formName"]
- 现有问题:
- window.event
- 现有问题:
使用 window.event 无法在 MF 上运行 - 解决方法:
MF 的 event 只能在事件发生的现场使用,此问题暂无法解决。可以这样变通:
原代码(可在 IE 中运行):
<input type="button" name="someButton" value="提交"/> ... <script language="javascript"> function gotoSubmit() { ... alert(window.event); // use window.event ... } </script>
新代码(可在 IE 和 MF 中运行):
<input type="button" name="someButton" value="提交"/> ... <script language="javascript"> function gotoSubmit(evt) { evt = evt ? evt : (window.event ? window.event : null); ... alert(evt); // use evt ... } </script>
此外,如果新代码中第一行不改,与老代码一样的话(即 gotoSubmit 调用没有给参数),则仍然只能在IE中运行,但不会出错。所以,这种方案 tpl 部分仍与老代码兼容。
- 现有问题:
- HTML 对象的 id 作为对象名的问题
- 现有问题:
在 IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 MF 中不能。 - 解决方法:
用 getElementById("idName") 代替 idName 作为对象变量使用。
- 现有问题:
- 用idName字符串取得对象的问题
- 现有问题:
在IE中,利用 eval(idName) 可以取得 id 为 idName 的 HTML 对象,在 MF 中不能。 - 解决方法:
用 getElementById(idName) 代替 eval(idName)。
- 现有问题:
- 变量名与某 HTML 对象 id 相同的问题
- 现有问题:
在 MF 中,因为对象 id 不作为 HTML 对象的名称,所以可以使用与 HTML 对象 id 相同的变量名,IE 中不能。 - 解决方法:
在声明变量时,一律加上 var ,以避免歧义,这样在 IE 中亦可正常运行。
此外,最好不要取与 HTML 对象 id 相同的变量名,以减少错误。 - 其它
参见 问题4
- 现有问题:
- event.x 与 event.y 问题
- 现有问题:
在IE 中,event 对象有 x, y 属性,MF中没有。 - 解决方法:
在MF中,与event.x 等效的是 event.pageX。但event.pageX IE中没有。
故采用 event.clientX 代替 event.x。在IE 中也有这个变量。
event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。
如果要完全一样,可以稍麻烦些:
mX = event.x ? event.x : event.pageX;
然后用 mX 代替 event.x - 其它
event.layerX 在 IE 与 MF 中都有,具体意义有无差别尚未试验。
- 现有问题:
- 关于 frame
- 现有问题:
在 IE 中可以用 window.testFrame 取得该 frame,MF 中不行。 - 解决方法:
在 frame 的使用方面 MF 和 IE 的最主要的区别是:
如果在 frame 标签中书写了以下属性:
<frame src="/xx.htm" id="frameId" name="frameName" />
那么 IE 可以通过 id 或者 name 访问这个 frame 对应的 window对象
而 MF 只可以通过 name 来访问这个 frame 对应的 window 对象
例如,如果上述 frame 标签写在最上层的 window 里面的 htm 里面,那么可以这样访问:
IE: window.top.frameId 或者 window.top.frameName 来访问这个 window 对象
MF: 只能这样 window.top.frameName 来访问这个 window 对象
可以通过iframeWindowObj=window.frames[softwaretech:'frameName'];来取得frame的window对象,FF IE通用。
另外,在 MF 和 IE 中都可以使用 window.top.document.getElementById("frameId")来访问 frame 标签
并且可以通过 window.top.document.getElementById("testFrame").src = 'xx.htm' 来切换 frame 的内容
也都可以通过 window.top.frameName.location = 'xx.htm' 来切换 frame 的内容
- 现有问题:
- 在 MF 中,自己定义的属性必须 getAttribute() 取得
- 在 MF 中没有 parentElement parement.children 而用 parentNode parentNode.childNodes
childNodes 的下标的含义在 IE 和 MF 中不同,MF 使用 DOM 规范,childNodes中 会插入空白文本节点。
一般可以通过 node.getElementsByTagName() 来回避这个问题。
当 html 中节点缺失时,IE 和 MF 对 parentNode 的解释不同,例如
<form> <table> <input/> </table> </form>
MF 中 input.parentNode 的值为 form, 而 IE 中 input.parentNode 的值为空节点
MF 中节点没有 removeNode 方法,必须使用如下方法 node.parentNode.removeChild(node) - const 问题
- 现有问题:
在 IE 中不能使用 const 关键字。如 const constVar = 32; 在 IE 中这是语法错误。 - 解决方法:
不使用 const ,以 var 代替。
- 现有问题:
- body 对象
MF 的 body 在 body 标签没有被浏览器完全读入之前就存在,而 IE 则必须在 body 完全被读入之后才存在 - url encoding
在 js 中如果书写 url 就直接写 不要写 & 例如:
var url = 'xx.jsp?objectName=xxobjectEvent=xxx';
frm.action = url; 那么很有可能 url 不会被正常显示以至于参数没有正确的传到服务器
一般会服务器报错参数没有找到
当然如果是在 tpl 中例外,因为 tpl 中符合 xml 规范,要求 书写为 &
一般 MF 无法识别 js 中的 - nodeName 和 tagName 问题
- 现有问题:
在MF中,所有节点均有 nodeName 值,但 textNode 没有 tagName 值。在 IE 中,nodeName 的使用好象有问题(具体情况没有测试,但我的 IE 已经死了好几次)。 - 解决方法:
使用 tagName,但应检测其是否为空。
- 现有问题:
- 元素属性
IE 下 input.type 属性为只读,但是 MF 下可以修改 - document.getElementsByName() 和 document.all[softwaretech:name] 的问题
在 IE 中,getElementsByName()、document.all[softwaretech:name] 均不能用来取得 div 元素(是否还有其它不能取的元素还不知道)。
可以对DIV对象设置相同的ID和name,比如4个DIV,都写成<div id='aa' name='aa'>xx</div>即可通过getElementsByName来取得对象数组。 - parentNode 和 parentElement 问题
- 现有问题:
在MF中,使用 parentElement 获得父对象,但没有 tagName 值。在 IE 中正常。 - 解决方法:
使用 parentNode 获取父对象,IE 和 MF 均可以取得 tagName 值
- 现有问题:
- YUI有个BUG,用
YAHOO.util.Event.on(window,"load",functino(){ YAHOO.util.Event.on(someObj,"click",fn) })
如果页面载入速度慢的话,如果用户在这个CLICK事件没有被添加的时候,用户就点了这个OBJ,那么这个CLIK就不会再被添加进去了。
今天还试了下,好象a的ONCLICK已经写了的话,用YAHOO来添加事件也会有点问题。
具体原因和解决方法正在寻找中。 - display:none的时候, offsetWidth, offsetHeight为0,
解决方案是先用visibility:hidden, 把上面两个值取到,再用display来操作 - 覆盖层级, div>iframe>select>div 很神奇吧, 所以解决select 覆盖div的问题, 只要在div和select中间加个iframe就OK了.
- innerHTML自动补齐标签
var dv; dv = document.createElement("div"); dv.id = id; dv.style.position="absolute"; dv.style.zIndex=z_index; dv.innerHTML="<a href=/"javascript:void()/"><img src=/"close.gif/" vspace=/"4/" border=/"0/" style=/"float:right;/" /></a>"; dv.innerHTML+="<h3>Select a Category</h3>"; dv.innerHTML+="<div class=/"opUpContent/">"+content+"</div>";
非常奇怪的现象, 如果我这样写dv.innerHTML+="<div class=/"opUpContent/">"; dv.innerHTML+=content; dv.innerHTML+="</div>";
那么innerHTML会自动把标签补齐. 于是innerHTML就变成了这样<div class="PopUpContent"></div>content<div></div>; - 一个table的代码如下,tr的parentNode是tbody,而不是table。这个tbody虽然没写, 但是存在与DOM中。
<table> <tr> <td></td> </tr> </table> - JS编码问题,当前页面gb2312,如果JS文件需要输出中文,那么JS文件本身保存的格式需要调整成UTF8,用UE来编辑的时候,选择文件-》转换-》ASCII转UTF8。
#PS:
为了保证网站能够与下一代的web 语言xml 标准兼容,所有的HTML 标签的属性都要用单引号或者双引号括起,即我们应该写 <a href="url"> 而不 是 <a href=url>.
如我们注意在源代码中不应有这样的代码:
<td><img src="../images/sample.gif"> </td>
而应该是这样的: <td><img src="../images/sample.gif"></td>
- document.form.item 问题
这是因为浏览器认为换行相当于一个半角空格,以上不规范的写法相当于无意中增加一个半角空格,如果确实有必要增加一个半角空格,也应该这样写:<td><img src="../images/sample.gif"> </td>
公用组件必须提取成js文件形式被引用,减少页面大小