最近在做項目的升級工作,主要是跨瀏覽器這塊,遇到了一些問題並且做了總結,貼出來與大家分享一下,如果你也遇到類似的問題,希望對你有一定的幫助。閒話少敘,進入正題,按照我總結的順序來吧。
1、獲取瀏覽器的版本,這個是很重要的,在做這個工作之初我就寫好了,因爲過程中總有無法兼容的情況,就必須進行瀏覽器判斷:
我封裝了一下,並且經過了測試【我這裏不考慮IE的兼容模式】,喜歡的朋友可以直接拿走。
- <span style="font-size:18px;">var BrowserType =
- {
- IE7: "MSIE 7.0",
- IE8: "MSIE 8.0",
- IE9: "MSIE 9.0",
- IE10: "MSIE 10.0",
- Chrome: "Chrome",
- Firefox: "Firefox",
- Safari: "Safari"
- };
- /// <summary>
- /// Get Browser version
- /// </summary>
- function getBrowserVersion()
- {
- if (navigator.userAgent.indexOf("MSIE 7.0") > 0)
- {
- return BrowserType.IE7;
- }
- if (navigator.userAgent.indexOf("MSIE 8.0") > 0)
- {
- return BrowserType.IE8;
- }
- if (navigator.userAgent.indexOf("MSIE 9.0") > 0)
- {
- return BrowserType.IE9;
- }
- if (navigator.userAgent.indexOf("MSIE 10.0") > 0)
- {
- return BrowserType.IE10;
- }
- if (navigator.userAgent.indexOf("Firefox") > 0)
- {
- return BrowserType.Firefox;
- }
- if (navigator.userAgent.indexOf("Chrome") > 0)
- {
- return BrowserType.Chrome;
- }
- if (navigator.userAgent.indexOf("Safari") > 0)
- {
- return BrowserType.Safari;
- }
- }</span>
2、關於IFrame的問題,這個在跨瀏覽器的時候你一定會碰到,這個我也封裝了兩個function,分享一下:
- <span style="font-size:18px;">/// <summary>
- /// Get iFrame DOM Function [IE、Firefox]
- /// </summary>
- function getIFrameDOM(id)
- {
- var iframeObj = null;
- if (document.getElementById(id) != null)
- {
- iframeObj = document.getElementById(id).contentDocument || document.frames[id];
- }
- return iframeObj
- }
- /// <summary>
- /// Get iFrame Window Function [IE、Firefox]
- /// </summary>
- function getIFrameWindow(id)
- {
- var iframeWindow = null;
- if (document.getElementById(id) != null)
- {
- iframeWindow = document.getElementById(id).contentWindow || document.frames[id].window;
- }
- return iframeWindow;
- }
- </span>
真正用的多是第二個方法,取iFrame的window,然後調用window下的方法。
3、關於IFrame加載完成的事件判斷--之前用的是IE的onreadystatechange
- <span style="font-size:18px;">if (getBrowserVersion() == BrowserType.IE8 || getBrowserVersion() == BrowserType.IE7)
- {
- $('#framePrintMap')[0].onreadystatechange = function ()
- {
- if (this.readyState == 'loaded' || this.readyState == 'complete')
- {
- var json = jQuery.parseJSON($('#hidDatas').val());
- var options = jQuery.parseJSON($('#hidOptions').val());
- getIFrameWindow('framePrintMap').initPrintMap(json, options);
- }
- }
- }
- else
- {
- $('#framePrintMap')[0].onload = function ()
- {
- if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')
- {
- var json = jQuery.parseJSON($('#hidDatas').val());
- var options = jQuery.parseJSON($('#hidOptions').val());
- getIFrameWindow('framePrintMap').initPrintMap(json, options);
- }
- }
- }
- $('#framePrintMap').attr('src', 'ThematicPrintMap.aspx');</span>
我詳細說下,如果是IE7和IE8,可以用onload事件,但是它沒有readyState對象,未加載完成直接調用iFrame裏面的方法,報錯了;IE9的話這兩個分支都可以了,onreadystatechange是隻有IE才支持,Safari/Chrome/Safari就只能走onload的分支了,那爲什麼還加個!readyState?是因爲在Firefox裏面沒有readyState對象,所以只能這樣判斷。
4、關於Table自動拉伸在跨瀏覽器的區別:請參見我的另一篇文章Table自動拉伸在Chrome與IE中的區別
5、關於各個瀏覽器對小數的處理:請參見我的另一篇文章各瀏覽器對小數處理取整情況的對比
6、關於捕獲鼠標位置在個瀏覽器中的差別:請參見我的另一篇文章JavaScript中鼠標event的位置在各瀏覽器中的異同
7、Chrome/Safari關於position:absolute的處理與其他瀏覽器有些不同:IE和Firefox會在父元素的內部,而Chrome/Safari會跑出父元素。
8、IE7與其他瀏覽器的text-align:center處理不一樣:IE7:內部的文本與div都居中,其他瀏覽器:只是文本居中,div不居中:將td中的內容包在div內部可以解決,td內的div的css爲text-align:left,div的css爲text-align:center,內部的文本就可以居中了。另一個顯示year的title的div也是同樣設置就可以了。
9、關於IE7的IE=EmulateIE7與IE=7及真正IE7的區別;請參考“瀏覽器模式”和“文檔模式”之間的區別
10、Chrome/Safari下點擊submit提交數據到後臺:如果數據量超過512k時會自動截斷,把input的type改成hidden就可以了。
11、父容器設置overflow:auto;子元素設置屬性position:relative;在ie7中該子元素不隨滾動條滾動:給設置了overflow:auto屬性的容器也加上position:relative就可以了。
12、Safari下時間Date.Parse時間不準確的問題:【有時候準確,有時候不準確,測試發現到了2034年之後就不準確了】,這個問題真是瀏覽器內核沒有做好,沒辦法,要兼容它還得想辦法:
先將日期轉化成自己定製的標準格式:
- <span style="font-size:18px;">Date.prototype.format = function (format)
- {
- var o =
- {
- "M+": this.getMonth() + 1, // month
- "d+": this.getDate(), // day
- "h+": this.getHours(), // hour
- "m+": this.getMinutes(), // minute
- "s+": this.getSeconds(), // second
- "q+": Math.floor((this.getMonth() + 3) / 3), // quarter
- "S": this.getMilliseconds() // millisecond
- }
- if (/(y+)/.test(format))
- {
- format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
- }
- for (var k in o)
- {
- if (new RegExp("(" + k + ")").test(format))
- {
- format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
- }
- }
- return format;
- }</span>
然後解析這個格式的時間就可以了,
- <span style="font-size:18px;">/// <summary>
- /// Time format:2011-10-01 00:00:00 *[SQL:120] || 2011/10/01[SQL:111]
- /// </summary>
- this.dateFromString = function (str)
- {
- var arr = str.split(/[^0-9]/);
- var curTime = null;
- if (arr.length == 3)
- {
- curTime = new Date(arr[0], arr[1] - 1, arr[2]);
- }
- else if (arr.length >= 6)
- {
- curTime = new Date(arr[0], arr[1] - 1, arr[2], arr[3], arr[4], arr[5]);
- }
- return curTime;
- }</span>
這個一般用在將時間綁定到某個元素的擴展屬性上,然後用的時候進行解析,div.data('time')。
13、Firefox下不支持嵌套function。