1. 程式人生 > >localstorage相容ie8以下瀏覽器的問題

localstorage相容ie8以下瀏覽器的問題

最近在做一個網站,由於希望儘可能減小伺服器的壓力,也想提高網站的運轉速度,就想盡可能少的在伺服器上讀寫資料以及下載重複資料,需要重複使用的資料,就儲存在本地,能在本地進行的運算,盡一切可能在本地完成。

於是就出現一個本地儲存資料的問題。如果ie不是國內最廣泛的瀏覽器,如果ie9(ie8存在一些問題,後面再說)已經得到普及,那麼一切就都很簡單了,用html5的localstorage,一切都變得異常簡單——谷歌瀏覽器早就支援localstorage了,但ie支援得很晚。

問題是,ie8以下的瀏覽器不支援localstorage;據說ie8支援localstorage,但我把ie升級到ie8之後,任然無法使用localstorage——一開始我以為是我的程式有問題,後來又覺得是ie8安裝有問題,重灌之後,我最終確定是ie8的升級程式有問題,微軟的東西總是這麼爛,早已習以為常了——這一來一去,差不多折騰了我三四個小時。

於是乎我確定,即便使用者瀏覽器是ie8,也要考慮無法使用localstorage的可能——而且從前段時間別人使用我的網站的情況來看,這種可能性還很大。

既然ie8要排除在外,而ie9只能在win7上使用,win7現在又遠未達到全面普及的程度——那麼就必須解決低版本ie使用localstorage的相容問題——真是生不逢時,再過幾年就根本不用考慮這個相容問題了。

由於我還屬於剛入門的菜鳥級程式設計師,所以很多東西根本弄不懂,坑爹的是這篇文章給的程式碼零零散散,沒法直接把它的程式碼直接嵌到程式裡,而要弄懂它程式碼的意思又需要大費周章,另外找到幾篇文章,把程式碼放進去,又會冒出一大堆我搞不懂的錯誤。

於是我決定從最基礎的原理開始,自己動手來做相容程式,別人沒有為你定做貼身的程式,就只有靠自己了,好在原理很簡單:

ie瀏覽器在很早的時候就支援一種UserData的本地儲存功能,不過ie的UserData用起來比localstorage麻煩得不止一點半點(當然二者的差異還不止於此),接下來要做的就是用UserData來模擬localstorage的所有功能。

localstorage有幾項核心功能:

1window.localStorage.getItem( key );——讀變數

2window.localStorage.setItem( key, value );——寫變數

3window.localStorage.removeItem( key );——刪除變數

4window.localStorage.clear(); ——變數初始化

5window.localStorage.length;——本地變數的個數;

6window.localStorage.key( i );——按序號讀取變數;

對於我做網站來說,最後兩個功能基本用不上,我就沒寫,但要實現也很簡單,如果你需要的話可以聯絡我,我們一起切磋。

接下來就是要用UserData前面幾項模擬功能,關於UserData的使用方法,我主要是參考了這篇文章:

不過這篇文章也有幾個坑爹的地方,讓我浪費了不少時間。

等我把UserData和localStorage的基本用法都弄懂了之後,我發現上面那篇介紹相容方法的文章有不少亮點,但也有很多不如人意的地方——最大的問題是他是採用了用節點儲存變數的方法,這樣的話變數的總大小不能超過124k,這個規模對我的網站來說太小了,於是我採用了用檔案儲存的方式,這樣變數大小就能達到1M,夠用了。

敲了幾個小時的鍵盤,反覆除錯後,這段程式碼終於可以用了。(程式碼在下面)

使用方法:

(1)把這段程式碼放在第一個進行本地儲存的語句之前的任何位置;

(2)程式碼必須在<html>標籤內;

(3)不能將本地變數名設為"userdata_record"

(4)不能以 userdataobj 命名變數

(5)加入程式碼後,如果不使用localStorage.length和localStorage.key( i ),那麼你就完全按照localStorage的使用方法進行本地儲存就可以了。

如果有問題歡迎和我聯絡。

<script language="JavaScript" type="text/javascript">

if(typeof(localStorage)=='undefined')

{var  box = document.body || document.getElementsByTagName("head")[0] || document.documentElement; 

      userdataobj = document.createElement('input'); 

      userdataobj.type = "hidden"; 

      userdataobj.addBehavior ("#default#userData"); 

      box.appendChild(userdataobj);

   //設定物件  

 var localStorage= {

      setItem:function(nam,val)

    {userdataobj.load(nam);

 userdataobj.setAttribute(nam,val);

 var d= new Date();

               d.setDate( d.getDate()+700); 

 userdataobj.expires=d.toUTCString(); 

 userdataobj.save(nam);

 userdataobj.load("userdata_record");

 var dt=userdataobj.getAttribute("userdata_record");

 if(dt==null)dt='';

 dt=dt+nam+",";

 userdataobj.setAttribute("userdata_record",dt);

 userdataobj.save("userdata_record");},

//模擬 setItem

 getItem:function(nam)

    {userdataobj.load(nam);

 return userdataobj.getAttribute(nam); },

//模擬 getItem

 removeItem:function(nam)

    {userdataobj.load(nam);

 clear_userdata(nam)

 userdataobj.load("userdata_record");

 var dt=userdataobj.getAttribute("userdata_record");

 var reg=new RegExp(nam+",","g");

 dt=dt.replace(reg,'');

 var d= new Date();

              d.setDate( d.getDate()+700); 

 userdataobj.expires= d.toUTCString();

 userdataobj.setAttribute("userdata_record",dt);

 userdataobj.save("userdata_record");

},

//模擬 removeItem

 clear:function(){

     userdataobj.load("userdata_record");

 var dt=userdataobj.getAttribute("userdata_record").split(","); 

     for (var i in dt)

   {if(dt[i]!='')clear_userdata(dt[i]) }

       clear_userdata("userdata_record")

 }

//模擬 clear();

}

function clear_userdata(keyname)//將名字為keyname的變數消除

{var keyname;

 var d= new Date();

          d.setDate( d.getDate()-1);

 userdataobj.load(keyname);

          userdataobj.expires=d.toUTCString();

 userdataobj.save(keyname);

}

}

</script>