首頁 > web前端 > js教程 > 主體

js頁面儲存之刷新內容不遺失實作方法

小云云
發布: 2018-03-16 17:12:57
原創
2872 人瀏覽過

HTML5 是下一代 HTML 標準,開始吸引越來越多人的目光。 HTML5 的 DOM Storage 機制提供了一種方式讓程式設計師能夠將資訊儲存到本機的電腦上,在需要時取得。這點和 cookie 相似,差異在於 DOM Storage 提供了更大容量的儲存空間。

  1. 下面是 DOM Storage 的接口定义:  
      
     interface Storage {   
      readonly attribute unsigned long length;   
      getter DOMString key(in unsigned long index);   
      getter any getItem(in DOMString key);   
      setter creator void setItem(in DOMString key, in any data);   
      deleter void removeItem(in DOMString key);   
      void clear();   
     };
    登入後複製

#目前,在客戶端保存資料使用最多的是cookie,但cookie 的大小上限為4KB,並且每次要求一個新頁面時cookie 都會被傳送過去。更多的儲存空間需要瀏覽器本身或是插件的支持,例如只在 Internet Explorer 上使用的 userData,需要額外安裝插件的 Google Gears 和 Flash。現在,HTML5 提供了一個標準的接口,使程式設計師可以簡單地存取儲存的資料。由於鍵值對儲存在本機上,因此在頁面載入完畢後可以透過 JavaScript 來操作這些資料。

DOM Storage

範例應用程式:使用者註冊

本文使用的範例應用程式是一個簡單的使用者註冊過程,表單包含三個欄位:name、age 和address,我們將其拆分為兩個表單,分成兩個頁面顯示。借助簡化了的資料模型,主要介紹如何利用 DOM Storage 功能處理表單跨頁問題。

DOM Storage 兩個分類

DOM Storage 分為 sessionStorage 和 localStorage。

localStorage 物件和 sessionStorage 物件使用方法基本上相同,它們的差異在於作用的範圍不同。 sessionStorage 用來儲存與頁面相關的數據,它在頁面關閉後無法使用。而 localStorage 則持久存在,在頁面關閉後也可以使用。

DOM Storage 介面

下面是DOM Storage 的介面定義:

 interface Storage { 
  readonly attribute unsigned long length; 
  getter DOMString key(in unsigned long index); 
  getter any getItem(in DOMString key); 
  setter creator void setItem(in DOMString key, in any data); 
  deleter void removeItem(in DOMString key); 
  void clear(); 
 };
登入後複製

length:傳回目前儲存在Storage 物件中的鍵值對數量。

key(index):傳回清單中第 n 個鍵的名字。 Index 從 0 開始。

getItem(key):傳回指定鍵對應的值。

setItem(key, value):存入一個鍵值對。

removeItem(key) :刪除指定的鍵值對。

clear():刪除 Storage 物件中的所有鍵值對。

通常,使用最多的方法是 getItem 和 setItem。

以sessionStorage 為例:

儲存鍵值對:

window.sessionStorage.setItem(“key1”, value1);

透過鍵名來讀取值:

var value1 = window.sessionStorage.getItem(“key1”);

判斷瀏覽器是否支援DOM Storage

要使用DOM Storage,首先,需要查看目前的瀏覽器是否支援。目前 Internet Explorer 8.0 以上,Firefox 3.5 以上,Chrome 4.0 以上都是支援 DOM Storage 的。

如果瀏覽器不支援 DOM Storage,可以用其他的方法作為備選,本文也使用 Dojo 提供的 dojox.storage 模組來實現相同的功能。

清單 1. 查看瀏覽器是否支援 DOM Storage

#
  1. //sessionStorage   
    if(window.sessionStorage){   
       alert(“support sessionStorage”);   
    }else{   
       alert(“not support sessionStorage”);   
       // 不支持 sessionStorage   
       // 用 dojox.storage 来实现相同功能  
    }   
      
    //localStorage   
    if(window.localStorage){   
       alert(“support localStorage”);   
    }else{   
       alert(“not support localStorage”);   
       // 不支持 localStorage   
       // 用 dojox.storage 来实现相同功能  
    }
    登入後複製

下面是用户注册的两个表单。清单 2 中的第一个表单有两个字段 name 和 age 需要用户填写内容。填写完后点击 Next 按钮进入下一个页面,此时函数 saveToStorage 会被调用,把在该页面输入的两个字段的值保存到 sessionStorage 对象中。

当从下一个页面退回到本页面时,使用 windows.onload 在加载页面的时候将数据从 sessionStorage 中取出,并显示在输入框中,方便用户修改。

另外,给对象赋值除了用 setItem 方法外,也可以用 window.sessionStorage.key1 = “value1”。

清单 2. 第一个表单页面

<script type="text/javascript">   
 // 当退回到第一个页面时,从 sessionStorage 得到用户之前输入的值并显示在页面,方便修改  
 window.onload = function(){   
    if (window.sessionStorage) {   
        var name = window.sessionStorage.getItem("name");   
        var age = window.sessionStorage.getItem("age");   
        if (name != "" || name != null){   
            document.getElementById("name").value = name;   
        }   
        if (age != "" || age != null){   
            document.getElementById("age").value = age;   
        }   
    }else   
    {   
        // 不支持 sessionStorage,用 Dojo 实现相同功能  
    }   
 };   
  
 // 将数据保存到 sessionStorage 对象中  
 function saveToStorage() {   
    //sessionStorage   
    if (window.sessionStorage) {   
        var name = document.getElementById("name").value;   
        var age = document.getElementById("age").value;   
        window.sessionStorage.setItem("name", name);   
        window.sessionStorage.setItem("age", age);   
        window.location.href="form2.html";   
    } else {   
        // 不支持 sessionStorage,用 Dojo 实现相同功能  
    }   
 }   
 </script>   
  
 <form action="./form2.html">   
    <input type="text" name="name" id="name">   
    <input type="text" name="age" id="age">   
    <input type="button" value="Next" onclick="saveToStorage()"></input>   
 </form>
登入後複製


清单 3 的第二个页面有一个 address 字段。当用户填写完毕后,点击 Submit 按钮提交页面,此时 addStorageValue 函数被调用,把保存在 sessionStorage 中的 name 和 age 值先赋给当前表单的两个隐藏字段,随后一起提交给下一个处理表单的页面。最后调用 removeItem 函数删除 name 和 age 值。

如果用户需要修改第一个页面填写的内容,可以点击 Back 按钮回到前一个页面,用户在前一个页面已经填写的内容会出现在 text 框中。

清单 3. 第二个表单页面

  1. <script type="text/javascript">   
    // 将保持在 sessionStorage 中的数据赋给表单的隐藏属性  
    function addStorageValue() {   
       //sessionStorage   
       if (window.sessionStorage) {   
           var name = window.sessionStorage.getItem("name");   
           var age = window.sessionStorage.getItem("age");   
           document.getElementById("name").value = name;   
           document.getElementById("age").value = age;   
           window.sessionStorage.removeItem("name");   
           window.sessionStorage.removeItem("age");   
       } else {   
           // 不支持 sessionStorage,用 Dojo 实现相同功能  
       }   
    }   
      
    function backToPreviousForm() {   
       window.location.href="form1.html";   
    }   
    </script>   
      
    <form action="./form3.php" method="post">   
       <input type="hidden" name="name" id="name">   
       <input type="hidden" name="age" id="age">   
       <input type="text" name="address" id="address">   
       <input type="button" value="Back" onclick="backToPreviousForm()">   
       <input type="submit" value="Submit" onclick="addStorageValue()"></input>   
    </form>
    登入後複製

使用 DOM Storage 需要注意的几点

保存在 Storage 对象的数据类型

当使用 DOM Storage 进行本地存储时,任何数据格式在 Storage 对象中都以字符串类型保存,所以如果保存的数据不是字符串,在读取的时候需要自己进行类型的转换。这里我们使用 JSON 将对象序列化之后再存储。

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。目前,JSON 已经是 JavaScript 标准的一部分,主流的浏览器对 JSON 支持都非常完善。

本文用到两个相关的函数

JSON.parse() 函数会把 JSON 对象转换为原来的数据类型。

JSON.stringify() 函数会把要保存的对象转换成 JSON 对象保存。

在清单 4 中,先把一个布尔型的数据存到 Storage 对象中,然后再取出,可以看到布尔类型的数据在取出的时候变为字符串。接下来换一种方式保存数据,先用 JSON.stringify 方法序列化数据,然后保存到 Storage 对象中,在取出的时候用 JSON.parse 方法进行反序列化,可以看到读取出的数据还是布尔类型。

另外,使用 JSON 保存一个字符串,通过 Chrome 的 Storage 工具,可以看到存入的字符串两边有双引号,这个双引号表示存入的是一个字符串。当用 JSON 表示一个简单的字符串时,会在字符串两边加上双引号。最后,该页面加载后的输出如下:

string1 boolean2 string3

  1. 清单 4. 使用 JSON 对 DOM Storage 的复杂数据进行处理  
      
     // 生成一个 Boolean 类型的变量 data1   
     var data1 = new Boolean(true);   
      
     // 不用 JSON 处理数据  
     sessionStorage["key1"] = data1;   
     if(sessionStorage["key1"] == "true"){   
        // 从 Storage 对象读取出来的数据 data1 变为 String 类型  
        document.write("string1 ");   
     }   
      
     // 使用 JSON 处理数据 data1   
     sessionStorage["key2"] = JSON.stringify(data1);   
     if(JSON.parse(sessionStorage["key2"]) == true){   
        // 从 Storage 对象读取的数据 data1,用 JSON 将变量转换为原来的 Boolean 类型  
        document.write("boolean2 ");   
     }   
      
     // 生成一个 String 类型的变量  
     var data2 = new String("true");   
     // 使用 JSON 处理数据,在 Storage 对象中保存的是 “string”  
     sessionStorage["key3"] = JSON.stringify(data2);   
     data2 = JSON.parse(sessionStorage["key3"]);   
     if(data2 == "true"){   
        // 变量转换回来还是 String 类型  
        document.write("string3");   
     }
    登入後複製

使用 Chrome 浏览器可以查看当前的 sessionStorage 和 localStorage 的键值对。在工具栏选择“工具”到“开发人员工具”到“Resources”到“Local Storage”或“Session Storage”, 可以查看 key 和 value。

图 1. Chrome 浏览器的 Storage 工具栏

图 1. Chrome 浏览器的 Storage 工具栏

综上所述,我们可以如清单 5 一样,在加载页面的时候用 JSON 转换数据类型,在离开页面的时候将数据保存为 JSON 对象。这样,保存在 Storage 中任何类型的数据在读取的时候都可以转换为原来的类型。

清单 5. 使用 JSON 对 DOM Storage 的复杂数据进行处理

<script type="text/javascript">   
 var value;   
 function loadValue() {   
    value1 = JSON.parse(window.sessionStorage.getItem(“key1”));   
 }   
 function saveValue() {   
    window.sessionStorage.setItem(“key1”) = JSON.stringify(value1);   
 }   
  
 window.addEventListener(“load”, loadValue. true);   
 window.addEventListener(“unload”, saveValue. true);   
 </script>
登入後複製

空间大小

HTML5 的建议是每个网站提供给 Storage 的空间是 5MB,一般来说足够存字符串。如果存入的数据太大,有些浏览器如 Chrome 会抛出 QUOTA_EXCEEDED_ERR 异常。所以虽然 DOM Storage 提供的空间比 cookie 要大很多,但在使用需要注意限制。

图 2. Chrome 浏览器抛出异常

图 2. Chrome 浏览器抛出异常

安全性

一般不要在客户端存储敏感的信息,使用 localStorage、globalStorage 等在客户端存储的信息都非常容易暴露。应该在完成数据存储后使用 clear 或者 removeItem 方法清除保存在 Storage 对象中的数据。

存储事件驱动

如果想在存储成功或修改存储的值时执行一些操作,可以用 DOM Storage 接口提供的事件。可以使用如下方法注册事件:

window.addEventListener(“storage”, handleStorageEvent, false);

存储事件接口定义


interface StorageEvent : Event {
readonly attribute DOMString key;
readonly attribute any oldValue;
readonly attribute any newValue;
readonly attribute DOMString url;
readonly attribute Storage storageArea;
void initStorageEvent(in DOMString typeArg, in boolean canBubbleArg, 
in boolean cancelableArg, in DOMString keyArg, in any oldValueArg, 
in any newValueArg, in DOMString urlArg, in Storage storageAreaArg);
};
登入後複製

key:发生改变的键。

oldValue:键改变之前的值。

newValue:键改变之后的值。

url:触发存储事件的页面 url。

在清单 6 中注册完存储事件后,当 sessionStorage 或者 localStorage 对象的值发生改变时,会触发 handleStorageEvent 函数,在页面显示发生改变的键和改变之前与之后的值。

清单 6. 添加存储事件

 // 显示存储事件的相关内容
 function handleStorageEvent(e) { 
    document.write(“key” + e.key + “oldValue” + e.oldValue + “newValue” + e.newValue); 
 } 
 // 添加存储事件监听
 window.addEventListener(“storage”, handleStorageEvent, false);
登入後複製

使用 Dojo 实现之前用户注册的功能

Dojo 是一个 JavaScript 实现的开源工具包,很大程度上屏蔽了浏览器之间的差异性。Dojo 扩展库 (dojox) 是 Dojo 在其基本库、核心库和 Dijit 库的基础上提供的一个非常丰富的组件仓库。本文用到的 dojox.storage 模块能够将数据保存在本地存储中,实现和之前 DOM Storage 一样的功能。

由于一些老版本浏览器不支持 HTML5,我们还可以用 Dojo 来实现之前用户注册的功能。相对于 HTML5 的 DOM Storage 接口,Dojo 的 dojox.storage.Provider 接口提供的方法更多。这里我们列出几个常用的方法。

get(key, namespace):返回指定键对应的值。

put(key, value, resultsHandler, namespace):存入一个键值对。

remove(key, namespace):删除指定的键值对。

clear(namespace):删除对象中的所有键值对。

现在对第一个表单的 JavaScript 代码做部分修改,并在页面中引入 dojox.storage 模块。这样,程序在不支持 HTML5 的浏览器中能够通过调用 Dojo 提供的方法正常运行。dojo.require("dojox.storage") 表示引入 dojox.storage 功能模块。然后通过 dojox.storage.manager.isInitialized() 查看 dojox.storage.manager 是否已经初始化,如果没有的话,则需要等待其初始化完成之后,再进行存储操作。

清单 7. 经过修改后的第一个表单页面的部分代码

 <script type="text/javascript"> 
 dojo.require("dojox.storage"); 
 // 当退回到第一个页面时,从 Storage 中得到用户之前输入的值并显示在页面,方便修改
 // 这里先进行 dojox.storage.manager 的初始化
 if(!dojox.storage.manager.isInitialized()){ 
    dojo.connect(dojox.storage.manager, "loaded", saveAndLoad); 
 } else{ 
    dojo.connect(dojo, "loaded", saveAndLoad); 
 } 
 function saveAndLoad(){ 
    var name; 
    var age; 
    //sessionStorage 
    if (window.sessionStorage) { 
        name = window.sessionStorage.getItem("name"); 
        age = window.sessionStorage.getItem("age"); 
        if (name != "" || name != null){ 
            document.getElementById("name").value = name; 
        } 
        if (age != "" || age != null){ 
            document.getElementById("age").value = age; 
        } 
    }//dojox.storage 
    else 
    { 
        name = dojox.storage.get("name"); 
        age = dojox.storage.get("age"); 
        if (typeof name != "undefined" ){ 
            document.getElementById("name").value = name; 
        } 
        if (typeof age != "undefined" ){ 
            document.getElementById("age").value = age; 
        } 
    } 
 } 

 // 保存数据
 function saveToStorage() { 
    var name = document.getElementById("name").value; 
    var age = document.getElementById("age").value; 
    //sessionStorage 
    if (window.sessionStorage) { 
        window.sessionStorage.setItem("name", name); 
        window.sessionStorage.setItem("age", age); 
    }//dojox.storage 
    else { 
        dojox.storage.put("name", name); 
        dojox.storage.put("age", age); 
    } 
    window.location.href="form2.html"; 
 } 
 </script>
登入後複製
清单 8. 经过修改后的第二个表单页面的部分代码

 <script type="text/javascript"> 
 dojo.require("dojox.storage"); 
 // 将保存在 sessionStorage 中的数据赋给表单的隐藏属性
 function addStorageValue() { 
    var name; 
    var age; 
    //sessionStorage 
    if (window.sessionStorage) { 
        name = window.sessionStorage.getItem("name"); 
        age = window.sessionStorage.getItem("age"); 
        document.getElementById("name").value = name; 
        document.getElementById("age").value = age; 
        window.sessionStorage.removeItem("name"); 
        window.sessionStorage.removeItem("age"); 
    }//dojox.storage 
    else { 
        name = dojox.storage.get("name"); 
        age = dojox.storage.get("age"); 
        document.getElementById("name").value = name; 
        document.getElementById("age").value = age; 
        dojox.storage.remove("name"); 
        dojox.storage.remove("age"); 
    } 
 } 

 function backToPreviousForm() { 
    window.location.href = "form1.html"; 
 } 
 </script>
登入後複製

相关推荐:

JS页面刷新的方法总结

以上是js頁面儲存之刷新內容不遺失實作方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板