写了一个多月JS,感觉如今可不比几年前只有IE6的年代,而且过去只是用JS写个Ajax或者是简单的表单验证,可如今写一个稍微复杂点的小应用,要兼容所有浏览器,才发现真是太难了,难怪FE是一个独立的工种,有别于我们这些Java工程师了。

  如果你也不是专业FE,那么估计也会跟我一样在这些地方翻船,或许你所遇到的情况比我这些还多,那么欢迎补充。

  1 首先是最简单的select标签,就有诸多不兼容:

  A、 cloneNode方法,对于非IE浏览器没有问题,对于IE浏览器,我遇到的问题包括:

  1)option selected的会clone不过去,然后会将第一个option作为selected值

  2)事件clone也会有问题

  B、Readonly:对于IE6,可以通过以下方法将select设为readonly:

  obj.onbeforeactive=function(){return false}

  obj.onfocus=function(){obj.blur();}

  obj.onmouseover=function(){obj.setCapture();}

  obj.onmouseout=function(){obj.releaseCapture();}

  对于其他浏览器,我采用的是元素替代法,动态创建一个input标签,把值赋给它,然后将select隐藏。

  C、select的z-index对于IE6无效,网上有很多关于这个讨论,JQuery采用一个iframe搞定

  D、动态添加option的方法不同,这个网上一搜一大堆

  E、对于onclick和onchange的响应不同,在FF下可以在onclick select时动态读取option值然后构建option,然后选中一个值后执行onchange事件,但是IE下不能这样做。

  2 css对offsetWidth之类的理解不同

  http://newleague.iteye.com/blog/765535

  3 对于vertical-align baseline的理解不同:

  http://w3help.org/zh-cn/causes/RD1016

  4 设置背景色

  element.style.backgroundColor

  在firefox下想改变颜色,必须先设为null,再设为其他颜色才行,即先取消原来的颜色。

  在IE下,想取消颜色,必须设为''才行,而换其他颜色,无需先去掉之前的颜色,而如果你设成了null,反倒不行了。

  5 不同浏览器去padding的理解不同

  6 不同浏览器对强制换行和强制不换行的理解不同:

  http://www.cftea.com/c/2009/01/QPDZU40MNW8FYYG3.asp

  最恶心的是对于IE6,如果是我是蚊子,那么在td上写了word-break:keep-all依然无效,必须在span上也写。

  7 获得head节点的方式不同

  在Firefox下可以用window.head,而所有浏览器都兼容的方式是document.getElementsByTagName('head')[0]

  8 往head上添加css code的方法不同,也就是动态添加

32 还有一个特悲剧的,IE下会把document.[formname.]控件Id当成那个控件,如果把一个控件比如input的id设为了submit,那么form.submit()就会报错。
    
    至于用不用var的区别,undefined和null的区别,Ajax构建的不同方式,这些一般的Java程序员都了解了。

    很多Java程序员也会使用JS框架,比如JQuery,Extjs和Dojo,她们都帮我们屏蔽了很多兼容性问题。
    Dojo提供了Java一样的面向对象机制。

    抛砖引玉,你还遇到过什么陷阱,那些FE都知道,而我们Java工程师不知道?

 

    有同学要求例子,有些只是小知识,有了链接,那么给一个我做的过程中写的实验程序吧,主要是验证select,还有readonly之后的input对于keypress等事件的响应:

    <html>

Html代码
以下是代码片段:
<head> 
<script> 
function addListener(element,e,fn){ 
if(element.addEventListener){ 
element.addEventListener(e,fn,false); 
} else { 
element.attachEvent("on" + e,fn); 
} 
} 

function getEventSource(event){ 
event = window.event?window.event:event; 
var source = event.target || event.srcElement; 
return source; 
} 


function init(e){ 
var provChoice= document.getElementById('prov'); 
fillPro(provChoice); 
addListener(provChoice,'change',fillCity); 
var coChoice= document.getElementById('country'); 
addListener(coChoice,'change',function(){alert('a');}); 
var selects=document.getElementsByTagName('select'); 
for(var i=0;i<selects.length;i++){ 
selects[i].cloneNode=function(deep){ 
var temp=document.createElement('div'); 
temp.innerHTML=this.outerHTML; 
return temp.childNodes[0]; 
} 


} 

document.getElementById('cloneCo').appendChild(coChoice.cloneNode(true)); 
var coTD= document.getElementById('co'); 
document.getElementById('r1').appendChild(coTD.cloneNode(true)); 

document.getElementById('abc').readOnly=true; 
document.getElementById('abc').onkeydown=function(e){ 
e.preventDefault(); 
e.stopPropagation(); 
} 

document.getElementById('abc').onkeypress=function(e){ 
alert('b'); 
} 

document.getElementById('abc').onchange=function(e){ 
alert('c'); 
} 

document.getElementById('abc').onblur=function(e){ 
alert('d'); 
document.getElementById('abc').value='add'; 
} 
} 

function fillPro(pro){ 
pro.options[0]=new Option('BJ','北京'); 
pro.options[1]=new Option('TJ','天津'); 
pro.options[2]=new Option('HLJ','黑龙江'); 
pro.options[3]=new Option('SH','上海'); 
} 

function fillCity(e){ 
var c= document.getElementById('city'); 
if( document.getElementById('prov').value=='黑龙江'){ 
c.options[0]=new Option('HRB','哈尔滨'); 
c.options[1]=new Option('MDJ','牡丹江'); 
c.options[2]=new Option('QQHR','齐齐哈尔'); 
c.options[3]=new Option('JMS','佳木斯'); 
} 


} 

</script> 
</head> 
<body onload='init(event)'> 
<table> 
<tr id='r1'> 
<td id='co'> 
<select id='country' name='country'> 
<option value='UK'>UK</option> 
<option value='USA'>USA</option> 
<option value='CHINA' selected>China</option> 
</select> 
</td> 
<td> 
<select id='prov' name='prov'></select> 
</td> 
<td> 
<select id='city' name='city'></select> 
</td> 
<td id='cloneCo'></td> 
<td> 
<input id='abc' value='0' onkeypress='return alert("a1"); '/> 
</td> 
<tr> 
<table> 

</body> 
</html>