【轉】整理瀏覽器對網(wǎng)頁的兼容性問題(一)——JS&DOM篇
一、 JS與DOM的兼容性:
(一) DOM節(jié)點的訪問:
1. 以前對DOM節(jié)點訪問一般用“document.All.元素ID屬性值”或者“document.元素ID屬性值”這種簡化的方法,在FireFox中有時不支持此方法。
解決辦法:標準的方法為“document.getElementById(‘元素ID屬性值’)”或者“document.getElementByName(‘元素Name屬性值’)[0]”或者“document.getElementByTagName(‘元素標簽名’)[0]”;
2. 集合類對象的()與[]的問題:以前的代碼中很多集合類對象的訪問使用(),IE可以正常解析,FireFox不支持。
解決辦法:改用[]作為下標符號。如:document.Forms(‘FormName’)改為document.Forms[‘FormName’];又如:document.getElementsByName(‘元素Name屬性值’)(1)改為document.getElementsByName(‘元素Name屬性值’)[1];
3. document.Form.Item的問題:FireFox不能正常解析形如:document.FormName.Item("ItemName")這樣的語句,但IE與FireFox都支持document.FormName.Elements["ElementName"]。
解決辦法:改用如下語句形式:document.FormName.Elements["ElementName"];
4. 在IE中,可以利用eval(‘元素ID屬性值’)的方法取得改HTML對象,FireFox不支持此種對象訪問方法。
解決辦法:用“document.getElementById(‘元素ID屬性值’)”的方法取得對象;
5. 在IE中可以通過ID屬性值或者Name屬性訪問這個Frame對象,而FireFox只可以通過Name屬性來訪問這個Frame對象;
IE和FireFox均可通過window.document. getElementById(‘FrameId屬性值’)來訪問這個Frame對象
6. 在IE中body對象要在<body>標簽完全讀入才會存在,而在FireFox中一開始就存在
7. 在IE中input標簽的type屬性是只讀的,但在FireFox中是可讀寫的
8. 在IE中getElementsByName()、document.all[name]均不能用來取得div元素
9. IE,FireFox以及其它瀏覽器對于Table標簽的操作都各不相同,在IE中不允許對Table和TR的innerHTML賦值,使用JS增加一個TR時,使用appendChild方法也不管用。
解決辦法:
//向Table追加一個空行:
var row = otable.insertRow(-1);
var cell = document.createElement("td");
cell.innerHTML = " ";
cell.className = "XXXX";
row.appendChild(cell);
10. 在FireFox節(jié)點中沒有removeNode方法,必須使用如下方法 node.parentNode.removeChild(node)
11. IE或者FireFox2.0.x下,可以使用window.location或window.location.href;但在FireFox1.5下,只能使用window.location
解決方法:使用window.location來代替window.location.href
12. IE與FireFox的訪問父元素有區(qū)別,IE為Obj.ParentElement屬性;FireFox為Obj.ParentNode屬性
解決辦法:因為FireFox與IE都支持DOM,因此統(tǒng)一用ParentNode屬性
13. FireFox不支持元素的innerText屬性,需用textContent
解決辦法:
if(navigator.appName.indexOf("Explorer") > -1){
document.getElementById('element').innerText = "my text";
} else{
document.getElementById('element').textContent = "my text";
}
14. FireFox不支持元素的HtmlText屬性
解決辦法:
rng = document.createRange();
el = document.getElementById(ElementId);
rng.setStartBefore(el);
htmlFrag = rng.createContextualFragment(content);
while (el.hasChildNodes()){ //清除原有內容,加入新內容
el.RemoveChild(el.LastChild);
}
el.AppendChild(htmlFrag);
15. 在IE下可以用<Img Id="pic" OnClick="this.src= ‘aa.php’" src="aa.php" style="cursor: pointer"/> 可以刷新圖片,但在FireFox下由于緩存問題不行。
解決辦法:
在地址后面加個隨機數(shù):編輯onclick事件代碼如下:"this.src=this.src+’?’+Math.random()"
16. 在訪問某一節(jié)點如childNodes[i]時,要獲得該節(jié)點的值而這個值是<![CDATA[]]類型,那么在IE中可支持這樣訪問childNodes[i].text或childNodes[i].firstChild.nodeValue;在FireFox只支持childNodes[i].firstChild.nodeValue
解決辦法:統(tǒng)一用childNodes[i].firstChild.nodeValue方法訪問節(jié)點元素值
17. 在形如
<root>
<en>text</en>
</root>
格式的XML,在IE中<en>是<root>的第一個子節(jié)點,可通過root.childNodes[0]或root.firstChild訪問,但在FireFox中<en>是<root>的第二個子節(jié)點,第一個子元素是換行符,NodeType是#text;如果將XML換成如下格式
<root><en>text</en></root>
在IE和FireFox中<en>都是<root>的第一個子節(jié)點
18. 在用JS創(chuàng)建單選按鈕上的方法上,IE與其它瀏覽器不同,要寫出通用的創(chuàng)建方法就需要一種瀏覽器嗅探機制(browser-sniffing);IE是唯一能夠識別uniqueID這一document對象專屬屬性的瀏覽器,故可用該屬性區(qū)分瀏覽器類型;代碼如下:
if(document.uniqueID){
//Internet Explorer
var radioButtion = document.createElement("<input type='radio' name='radioButtion' value ='checked'>");
}else{
//Standards Compliant
var readioButtion = document.createElement("input");
readioButtion.setAttribute("type","radio");
readioButtion.setAttribute("name","radioButtion");
readioButtion.setAttribute("value","checked");
}
19. 刪除select列表標簽的列表項應該用obj.remove(i);而不是用obj.options.remove(i);
20. 添加select列表標簽的列表項應該用
var oOption = document.createElement('option');
oOption.text = text;
oOption.value = value;
targetArea.options[targetArea.options.length]= oOption; //new Option(text,value);
而不是用
var oOption = document.createElement('option');
oOption.text = text;
oOption.value = value;
targetArea.options.add(oOption);
21. IE中一般這樣初始化一個XMLDOM對象
var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
FireFox不支持該方法(具體原因參見四.JS的語法兼容性.6.),兼容性代碼如下
if (window.ActiveXObject){
var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
}else{
if (document.implementation && document.implementation.createDocument){
var xmlDom = document.implementation.createDocument("","",null);
}
}
有關不同瀏覽器對XMLDOM操作的異同請參見《IE和FireFox瀏覽器讀取XML方法比較》
(二) DOM節(jié)點屬性的訪問:
1. 原來在IE中設置HTML對象屬性的方法如:document.all.apple.width=100或者apple.width=100;現(xiàn)在為了能夠和FireFox兼容,對象屬性的設置寫為:document.getElementById(‘元素ID屬性值’).setAttribute(‘width’, ‘100’)
document.getElementsByTagName(‘元素標簽名’)[0].setAttribute(‘width’, ‘100’)
對象屬性的獲取寫為:
document.getElementById(‘元素ID屬性值’).getAttribute(‘width’)
document.getElementsByTagName(‘元素標簽名’)[0].getAttribute(‘width’)
2. (接上條) 在IE下不能正確使用setAttribute來設置對象的style、class以及事件響應屬性, 因此還得按原來的方法來訪問和設置,以達到兼容各種瀏覽器的效果
如下例:
document.getElementById(‘元素ID屬性值’).class
document.getElementById(‘元素ID屬性值’).style.color
document.getElementById(‘元素ID屬性值’).onclick
document.getElementById(‘元素ID屬性值’).class="classname"
document.getElementById(‘元素ID屬性值’).style.color="colorname"
document.getElementById(‘元素ID屬性值’).onclick= function(){alert(‘函數(shù)內容’)}
3. 在FireFox中,自己定義的屬性必須用getAttribute()方法獲取,不能像在IE下直接獲取
解決辦法:統(tǒng)一用getAttribute()方法獲取
4. img標簽具有title和alt兩個屬性,title用作圖片的tip說明,alt用在圖片不存在或加載失敗時的提示;在IE中若未定義title則alt也承擔了title的作用,但在FireFox則各司其職;因此為保證瀏覽器兼容最好各盡其用
5. IE中要操作某個節(jié)點(Node)的class要用”classname”做為屬性名來設置或取得,FireFox和其它瀏覽器用”class”做為屬性名來設置或取得
6. 設置某個節(jié)點(Node)的style,如果用”style” 做為屬性名其它瀏覽器都能解析,但IE會忽略;如果用”cssText” 做為屬性名其它瀏覽器都能解析,但Opera會忽略;通用代碼如下:
var oStyle = oNode.getAttribute("style");
if(oStyle == "[object]"){
oStyle.setAttribute("cssText", strStyle);
oNode.setAttribute("style", oStyle);
}else{
oNode.setAttribute("style", strStyle);
}
(三) DOM事件(event)的使用:
1. IE下一般用document.body.onload = onload_func這樣的方法注冊onload響應事件函數(shù),其中function onload_func()在這之前已經(jīng)被實現(xiàn),但是在FireFox下卻無法執(zhí)行; FireFox下一般用document.body.onload = onload_func()這樣的方法。
解決辦法:都采用window.onload = onload_func這種方法;或者都采用document.body.onload = new Function('onload_func'); 或者都采用document.body.onload = function(){/* … … */}。(注意Function與function的區(qū)別)
2. FireFox的event只能在事件發(fā)生的現(xiàn)場使用,此問題暫無法解決。可以這樣變通:
原代碼(可在IE中運行):
<input type="button" name="someButton" value="提交" onclick="javascript:gotoSubmit()"/>
...
<script language="javascript">
function gotoSubmit(){
...
alert(window.event); // use window.event
...
}
</script>
新代碼(可在IE和FireFox中運行):
<input type="button" name="someButton" value="提交" onclick="javascript:gotoSubmit(event)"/>
...
<script language="javascript">
function gotoSubmit(evt) {
evt = evt ? evt : (window.event ? window.event : null);
...
alert(evt); // use evt
...
}
</script>
此外,如果新代碼中第一行不改,與原代碼相同的話(即gotoSubmit調用沒有給參數(shù)),則仍然只能在IE中運行,但不會報錯。
3. 在IE中,event對象有x、y兩屬性,FireFox中沒有;相對的在FireFox中,event對象有pageX、pageY兩屬性,IE中沒有。
解決辦法:用event.clientX、event.clientY代替,缺陷是在頁面中存在滾動條時與pageX、pageY有細微差別;或者用如下方法代替:
pgX = event.x ? event.x : event.pageX;
pgY = event.y ? event.y : event.pageY;
可取得無差別數(shù)值。
4. 在IE中event對象有srcElement屬性,但是沒有target屬性; 在Firefox中event對象有target屬性,但是沒有srcElement屬性
解決辦法:用obj = event.srcElement ? event.srcElement : event.target;來代替IE下的event.srcElement或者Firefox下的event.target,請同時注意event的兼容性問題。
5. 添加事件捕獲 IE中:obj.setCapture()、obj.releaseCapture()
FireFox中:document.addEventListener( "mousemover",mousemovefunction,true);
document.removeEventListener( "mousemove ",mousemovefunction,true);
6. 禁止選取網(wǎng)頁內容 IE中用JS:obj.OnSelectStart=function(){return false;}
FireFox中用CSS:-moz-user-select:none
(四) JS的語法兼容性:
1. 在FireFox中可以使用與HTML節(jié)點對象ID屬性值相同的JS變量名稱,但是IE中不行。
解決辦法:在命名上區(qū)分HTML節(jié)點對象ID屬性值和JS變量
2. IE不支持JS的const,無法定義JS常量
解決辦法:全部用var定義為變量
3. 在JS中書寫URL地址字符串時&字符就直接寫為“&”(去掉雙引號),不要寫“&”,否則容易出現(xiàn)URL識別不正常的錯誤
4. 在IE中可以通過showModalDialog和showModelessDialog打開模式和非模式窗口,FireFox下則不能
解決辦法:使用Window.Open方法。 如果需要將子窗口中的參數(shù)傳遞回父窗口,可以在子窗口中使用Window.Opener屬性來訪問父窗口;如果需要父窗口控制子窗口的話,使用Var subWindow = Window.Open(pageURL,Name,Parameters); 來獲得新開的窗口對象
5. 在IE中向表格里添加一行的方法insertRow()如果不指定參數(shù),默認參數(shù)為-1,將自動向Table中追加1行;在FireFox中一定要指定參數(shù)如-1,參數(shù)為空會報錯
6. 在IE中可以使用new ActiveXObject()的方法實例化對象,如var xmlDom = new ActiveXObject("Microsoft.XMLHTTP");但是FireFox不支持ActiveXObject,只能通過這種方法如var xmlDom = new XMLHttpRequest();實例化對象