HTML5新特性之离线缓存技术实战

八、离线Web应用实战。

通过一个简单的记事本程序——PermaNote,来解释如何使用。程序将用户的文本保存到localStorage中,并且在网络连接可用的时候,

将其上传到服务器,PermaNote只允许用户编辑单个笔记。

PermaNote应用包含3个文件,一个应用清单文件、一个html页面文件,一个实现逻辑的js文件。

Demo: http://xuanfengge.com/demo/201506/appcache/permanote.html

①.premanote.appcache部分:


CACHE MANIFEST
#  PermaNote v8
permanote.html
permanote.js
NETWORK:
note
②.permanote.html部分:

<!DOCTYPEHTML>
<html manifest= permanote.appcache”>
     <head>
          <title>PermaNote Editor</title>
          <script src=” permanote.js”></script>
           <style type=”text/css”>
                 #editor {width:100%;height:250px}
                 #statusline{width:100%}
            </style>
      </head>
       <body>
               <div id=”toobar”>
                    <button id=”savebutton”onclick = “save()”>save</button>
                    <button onclick = “sync()”>SyncNote</button>
                    <button onclick = “applicationCache.update()”>UpdateApplication</button>
                      <textarea id=”editor”></textarea>
                       <div id=”statusline”></div>
               </div>
      </body>
</html>

③.permanote.js部分
status()函数用于显示状态栏消息,save()函数将笔记本保存到服务器,sync()用于确保本地与服务器文本的同步。

应用程序的时间处理程序解释:

(1).onload

尝试和服务器同步,一旦有新版本的笔记并且完成同步后,就启用编辑器窗口。

save()和sync()函数发出HTTP请求,并在XMLHttpRequest对象上注册一个onload时间处理程序来获取上传或者

下载完成的提醒。

(2).onbeforeunload

在未上传前,把当前版本的笔记数据保存到服务器上。

(3).oninput

每当textarea输入框内容发生变化时,都将其内容保存到localStorage中,并启动一个计时器。当用户停止编辑超过5秒

,将自动把数据保存到服务器。

(4).onoffline

当浏览器进入离线状态时,在状态栏显示离线消息。

(5).ononline
当浏览器回到在线状态时,同步服务器,检查是否有新版本的数据,并且保存当前版本的数据。

(6).onupdateready

如果新版本的应用已缓存,则在状态栏展示消息告知用户。

(7).onnoupdate

// 定义全局变量
var editor, statusline, savebutton, idletimer;
 
// 首次载入应用
window.onload = function() {
    // 第一次载入时,初始化本地保存
    if (localStorage.note == null) localStorage.note = "";
    if (localStorage.lastModified == null) localStorage.lastModified = 0;
    if (localStorage.lastSaved == null) localStorage.lastSaved = 0;
 
    // 查找编辑器UI元素,并初始化全局变量
    editor = document.getElementById("editor");
    statusline = document.getElementById("statusline");
    savebutton = document.getElementById("savebutton");
 
    editor.value = localStorage.note; // 初始化编辑器,将保存的笔记数据填充到内容
    editor.disabled = true;           // 同步前禁止编辑
 
    // 当输入框内容发生变化
    editor.addEventListener("input",
                            function (e) {
                                // 将新的内容保存至localStorage
                                localStorage.note = editor.value;
                                localStorage.lastModified = Date.now();
                                // 重置闲置计时器
                                if (idletimer) clearTimeout(idletimer);
                                idletimer = setTimeout(save, 5000);
                                // 启用保存按钮
                                savebutton.disabled = false;
                            },
                            false);
 
    // 每次载入应用程序时,尝试同步服务器
    sync();
};
 
// 离开页面钱保存数据到服务器
window.onbeforeunload = function() {
    if (localStorage.lastModified > localStorage.lastSaved)
        save();
};
 
// 离线时,告知用户
window.onoffline = function() { status("Offline"); }
 
// 再次返回在线状态时,进行同步
window.ononline = function() { sync(); };
 
// 当有新版本应用的时候,提醒用户
// 也可使用location.reload()放大来强制刷新应用
window.applicationCache.onupdateready = function() {
    status("A new version of this application is available. Reload to run it");
};
 
// 当没有新版本的时候也通知用户
window.applicationCache.onnoupdate = function() {
    status("You are running the latest version of the application.");
};
 
// 状态栏显示相关信息提示
function status(msg) { statusline.innerHTML = msg; }
 
// 每当笔记本内容更新后,如果用户停止编辑超过5分钟
// 就会自动将笔记文本上传至服务器(在线状态下)
function save() {
    if (idletimer) clearTimeout(idletimer);
    idletimer = null;
 
    if (navigator.onLine) {
        var xhr = new XMLHttpRequest();
        xhr.open("PUT", "/note");
        xhr.send(editor.value);
        xhr.onload = function() {
            localStorage.lastSaved = Date.now();
            savebutton.disabled = true;
        };
    }
}
 
// 检查服务端是否有新版本的笔记,若无,则将当前版本保存到服务器端
function sync() {
   if (navigator.onLine) {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "/note");
        xhr.send();
        xhr.onload = function() {
            var remoteModTime = 0;
            if (xhr.status == 200) {
                var remoteModTime = xhr.getResponseHeader("Last-Modified");
                remoteModTime = new Date(remoteModTime).getTime();
            }
 
            if (remoteModTime > localStorage.lastModified) {
                status("Newer note found on server.");
                var useit =
                    confirm("There is a newer version of the note\n" +
                            "on the server. Click Ok to use that version\n"+
                            "or click Cancel to continue editing this\n"+
                            "version and overwrite the server");
                var now = Date.now();
                if (useit) {
                    editor.value = localStorage.note = xhr.responseText;
                    localStorage.lastSaved = now;
                    status("Newest version downloaded.");
                }
                else 
                    status("Ignoring newer version of the note.");
                localStorage.lastModified = now;
            }
            else
                status("You are editing the current version of the note.");
 
            if (localStorage.lastModified > localStorage.lastSaved) {
                save();
            }
 
            editor.disabled = false;  // 再次启用编辑器
            editor.focus();           // 将光标定位到编辑器中
        }
    }
    else { // 离线状态下,不能同步
        status("Can't sync while offline");
        editor.disabled = false;
        editor.focus();
    }
}
 

猜你喜欢

转载自blog.csdn.net/qq_31965515/article/details/85682345