## 离线应用 离线Web应用,是指在设备不能上网的情况下仍然可以运行的应用。 要开发离线Web应用,需要下列几个步骤: - 检测设备是否能上网 - 应用能访问一定的资源(图像、JavaScript、CSS等) - 有一块本地空间用于保存数据 **1.1 离线检测** HTML5定义了一个`navigator.onLine`属性,用来检测设备是在线还是离线,为true时表示设备能上网,否则表示设备离线。 检测代码: ``` if (navigator.onLine){ // 正常工作 } else { // 设备已离线 } ``` 除了`navigator.onLine`属性,HTML5还为检测网络是否可用提供了两个事件:`online`和`offline`。 - `online`:当网络从离线变为在线时触发 - `offline`:当网络从在线变为离线时触发 ``` window.addEventListener('online', function(){ // 在线 }); window.addEventListener('offline', function(){ // 离线 }); ``` 为了检测应用是否离线,在页面加载后,最好先通过`navigator.onLine`取得初始的状态,然后再通过`online`和`offfline`两个事件检测网络连接状态是否变化。 **1.2 应用缓存** HTML5的应用缓存(application cache),简称:appcache,是专门为开发离线Web应用而设计的。 Appcache就是从浏览器的缓存中分出来的一块缓存区。要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源。 `manifest` 文件可分为三个部分: - CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存 - NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存 - FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面) ``` CACHE MANIFEST CACHE: # 需要缓存的列表 test.css test.jpg test.js NETWORK: # 不需要缓存的 test2.jpg FALLBACK: # 访问缓存失败后,备用访问的资源,第一个是访问源,第二个是替换文件*.html /offline.html 2.jpg/3.jpg ``` `#`是注释的意思。 注意:必须以`CACHE MANIFEST`开头 可以在`<html>`中的`manifest`属性中指定离线文件的路径,就可以将描述文件与页面关联起来了。 ``` <html manifest="offline.manifest"> ``` 注意:manifest文件的`MIME`类型必须是"text/cache-manifest"。 > 描述文件的扩展名以前推荐用manifest,现在推荐用appcache **1.2.1 applicationCache对象** JavaScript提供了相应的API让我们去监控描述文件的状态,这个API的核心是`applicationCache`对象(全局),这个对象有一个`status`属性,属性的值是常量,可能值如下: - 0:无缓存(UNCACHE),即没有与页面相关的应用缓存 - 1:闲置(IDLE),即应用缓存未得到更新 - 2:检查中(CHECKING),即正在下载描述文件并检测更新 - 3:下载中(DOWNLOADING),即应用缓存正在下载描述文件中指定的资源 - 4:更新完成(UPDATEREADY),即应用缓存已经更新了资源,而且所有资源都已下载完毕,可以通过swapCache()来使用了 - 5:废弃(IDLE),即应用缓存的描述文件已经不存在了。 **1.2.2 应用缓存相关事件** 应用缓存还有很多相关的事件,表示其状态的改变: - `checking`:在浏览器为应用缓存查找更新时触发 - `error`:在检测更新或下载资源期间发生错误时触发 - `noupdate`:在检查描述文件发生文件无变化时触发 - `downloading`:在开始下载应用缓存资源时触发 - `progress`:在文件下载应用缓存的过程中持续不断的触发 - `updateready`:在页面新的应用缓存下载完毕且通过swapCache()使用时触发 - `cached`:在应用缓存完整可用时触发 ``` applicationCache.addEventListener('updateready', function(){ if(applicationCache == 4) { //4等于application.UPDATEREADY applicationCache.swapCache(); //使用新版本资源 window.location.reload(); // 刷新页面 } }, false); ``` 使用`on`方式也可以: ``` applicationCache.ondownloading = function(){ } ``` 我们可以通过update()方法来手动检查更新: ``` applicationCache.update(); ``` **1.3 更新问题** 这里还要提一个关键问题,在线状态下,浏览器会检测描述文件是否有更新,而并不会检测描述文件内的相应文件是否更新。 比如有一个描述文件如下: ``` CACHE MANIFEST # Version 1 test.js ``` 当你修改了test.js里的内容时,浏览器并不会在检测描述文件时检测到这文件的变化,应该改成这样: ``` CACHE MANIFEST # Version 2(更改这个数字让浏览重新下载描述文件) test.js ```