一、HTML4客戶端存儲
B/S架構的應用大量的信息存儲在服務器端,客戶端通過請求響應的方式從服務器獲得數據,這樣集中存儲也會給服務器帶來相應的壓力,有些數據可以直接存儲在客戶端,傳統的Web技術中會使用Cookie,但Cookie有一些缺點,為了說明這個缺點我們先看看當提交表單時會有那些信息會被瀏覽器收集后發送到服務器。
1.1、提交表單發送到服務器的信息
1)、帶name的可用表單元素
2)、url
3)、客戶端請求頭部信息
4)、cookie
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% //定義一個cookie對象 Cookie cookie=new Cookie("color", "blue"); //設置過期時間為365小時,以秒為單位 cookie.setMaxAge(60*60*365); //添加cookie response.addCookie(cookie); %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title>提交表單測試</title> </head> <body> <form action="target.do?id=1" method="post"> <h2>提交表單測試</h2> <p> 名稱:<input type="text" name="txtName" id="txtName1" /> </p> <p> 價格:<input type="text" name="txtPrice" id="txtPrice1" value="888" readonly="readonly"/> </p> <p> 數量:<input type="text" name="txtAmount" id="txtAmount1" value="999" disabled="disabled"/> </p> <input type="hidden" id="key" value="123445"> <input type="submit" value="提交" /> </form> </body> </html>
運行結果:

服務器在響應頭部中聲明要求客戶端瀏覽器指定設置cookie color=blue的工作,且指定了過期時間,會將cookie信息記錄在本地,查看結果如下:

當提交信息給服務器時cookie將收集后返回服務器,同時也會將url、帶name可用的表單及請求頭部信息如user-agent等,結果如下:

1.2、客戶端本地存儲概要
顧名思義客戶端本地存儲就是將信息存儲在客戶端電腦上,cookie就是一種典型的傳統客戶端存儲,長期以來本地存儲能力一直是桌面應用區別於Web應用的一個主要優勢,作為Web應用程序而言,新一代的HTML標准對數據的本地存儲提出了更高的要求。傳統的Web數據存儲方式一直來使用的是Cookie,但Cookie有以下缺陷:
a)、cookie會被附加在每個HTTP請求中,所以無形中增加了流量。
b)、由於在HTTP請求中的cookie是明文傳遞的,所以安全性成問題。
c)、Cookie的大小限制在4 KB左右,容量達不到要求。
HTML5中的Web Storage,稱為Web本地存儲,在Web客戶端儲存數據的功能,用鍵值對的形式保存數據,曾經屬於HTML5的規范,目前已經被獨立出來形成單獨的規范體系。本地存儲優勢:
a)、統一的標准,兼容性高(IE8、各大瀏覽器支持)
b)、數據存儲量大
c)、無需安裝插件
d)、減少網絡流量
e)、更加適合移動端
HTML5 提供了四種在客戶端存儲數據的新方法,即localStorage 、sessionStorage、globalStorage、Web Sql Database。 前面三個適用於存儲較少的數據,而Web Sql Database適用於存儲大型的,復雜的數據,我習慣把前面的三個稱之為小存儲。 IE8、Firefox3.6、Chrome5、Safari4、Opera10,事實證明各個瀏覽器在API方面的實現基本上一致,存在一定的兼容性問題,但不影響正常使用。
在chrome瀏覽器中可以使用開發者工具查看到各種不同的本地存儲方式,如下圖所示:

Web SQL Database 和 Indexed Database 都是在客戶端存儲大量結構化數據的解決方案。Web SQL Database 實現了傳統的基於 SQL 語句的數據庫操作,而 Indexed Database 實現了 NoSQL 的存儲方式。
二、localStorage
localStorage:將數據保存在客戶端本地的硬件設備(通常指硬盤,但也可以是其他硬件設備)中,即使瀏覽器被關閉了,該數據仍然存在,下次打開瀏覽器訪問網站時仍然可以繼續使用。
2.1、添加
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>localStorage 本地存儲</title> </head> <body> <h2>localStorage 本地存儲</h2> <button onclick="add_click()">添加</button> <script type="text/javascript"> function add_click() { //向本地存儲中添加一個名為name,值為"手機"的key-value對象 localStorage.setItem("name","手機"); //辦法2 localStorage["price"]=999.5; //辦法3 localStorage.amount=1788; } </script> </body> </html>
運行結果:

2.2、取值
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>localStorage 本地存儲</title> </head> <body> <h2>localStorage 本地存儲</h2> <button onclick="add_click()">添加</button> <button onclick="get_click()">取值</button> <h3 id="msg"></h3> <a href="d02.html">d02.html</a> <script type="text/javascript"> var msg=document.getElementById("msg"); //添加 function add_click() { //向本地存儲中添加一個名為name,值為"手機"的key-value對象 localStorage.setItem("name","手機"); //辦法2 localStorage["price"]=999.5; //辦法3 localStorage.amount=1788; } //取值 function get_click() { msg.innerHTML+=localStorage.getItem("name")+"<br/>"; msg.innerHTML+=localStorage["price"]+"<br/>"; msg.innerHTML+=localStorage.amount+"<br/>"; } </script> </body> </html>
運行結果:

2.3、修改
//修改 function update_click() { //如果不存在就添加,如果存在就修改 localStorage.setItem("name","iPhone 8 plus手機"); //修改辦法2 localStorage["price"]=899.5; //修改辦法3 localStorage.amount=100; }
運行結果:

2.4、刪除
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>localStorage 本地存儲</title> </head> <body> <h2>localStorage 本地存儲</h2> <button onclick="add_click()">添加</button> <button onclick="get_click()">取值</button> <button onclick="update_click()">修改</button> <button onclick="delete_click()">刪除</button> <h3 id="msg"></h3> <a href="d02.html">d02.html</a> <script type="text/javascript"> var msg=document.getElementById("msg"); //添加 function add_click() { //向本地存儲中添加一個名為name,值為"手機"的key-value對象 localStorage.setItem("name","手機"); //添加辦法2 localStorage["price"]=999.5; //添加辦法3 localStorage.amount=1788; } //取值 function get_click() { msg.innerHTML+=localStorage.getItem("name")+"<br/>"; msg.innerHTML+=localStorage["price"]+"<br/>"; msg.innerHTML+=localStorage.amount+"<br/>"; } //修改 function update_click() { //如果不存在就添加,如果存在就修改 localStorage.setItem("name","iPhone 8 plus手機"); //修改辦法2 localStorage["price"]=899.5; //修改辦法3 localStorage.amount=100; } //刪除 function delete_click() { //根據鍵刪除 //localStorage.removeItem("price"); //刪除所有 localStorage.clear(); } </script> </body> </html>
運行結果:

2.5、跨頁面與跨域
當關閉瀏覽器,下次再打開時,值仍然存在。可以跨頁面,不能跨域。我們在d01頁面中添加了值,在d02頁面中仍然可以訪問,在整個同域下都可以訪問。

2.6、存儲位置與SQLite
localStorage與cookie不一樣,它存儲在一個數據庫文件中,默認位置在:C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\databases\http_localhost_*

使用SQLite數據庫管理工具,打開后看到的結果,這里以taobao存儲客戶端的localStorage為例:

提示:SQLite,是一款輕型的免費開源的數據庫,是遵守ACID的關系型數據庫管理系統,它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域項目。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統,同時能夠跟很多程序語言相結合,比如 Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起Mysql、PostgreSQL這兩款開源的世界著名數據庫管理系統來講,它的處理速度比他們都快。SQLite第一個Alpha版本誕生於2000年5月。 至2015年已經有15個年頭,SQLite也迎來了一個版本 SQLite 3已經發布。
SQLiteSpy管理工具下載:http://pan.baidu.com/s/1i5JQtBf
2.7、用途、練習與兼容性
所有需要將少量(不超過4M)數據存儲在客戶端的需求都適用,如密碼,用戶偏好(profile)等

登錄成功后記錄用戶訪問次數。
在IE8中測試通過

Firefox測試通過

三、sessionStorage
將數據臨時保存在客戶端session對象中。session對象就是會話對象,session中存儲的數據獨立於每個客戶,該數據會隨着瀏覽器的關閉而消失。
sessionStorage的操作api與localStorage基本一樣,在不手動清除的情況下localStorage永久保存,而sessionStorage只是臨時暫存。
3.1、sessionStorage使用
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>sessionStorage 本地存儲</title> </head> <body> <h2>sessionStorage 本地存儲</h2> <button onclick="add_click()">添加</button> <button onclick="get_click()">取值</button> <button onclick="update_click()">修改</button> <button onclick="delete_click()">刪除</button> <h3 id="msg"></h3> <a href="d04.html">d04.html</a> <script type="text/javascript"> var msg=document.getElementById("msg"); //添加 function add_click() { //向本地存儲中添加一個名為name,值為"手機"的key-value對象 sessionStorage.setItem("name","手機"); //添加辦法2 sessionStorage["price"]=999.5; //添加辦法3 sessionStorage.amount=1788; } //取值 function get_click() { msg.innerHTML+=sessionStorage.getItem("name")+"<br/>"; msg.innerHTML+=sessionStorage["price"]+"<br/>"; msg.innerHTML+=sessionStorage.amount+"<br/>"; } //修改 function update_click() { //如果不存在就添加,如果存在就修改 sessionStorage.setItem("name","iPhone 8 plus手機"); //修改辦法2 sessionStorage["price"]=899.5; //修改辦法3 sessionStorage.amount=100; } //刪除 function delete_click() { //根據鍵刪除 //sessionStorage.removeItem("price"); //刪除所有 sessionStorage.clear(); } </script> </body> </html>
運行結果:

可以實現在頁面間傳值,比如可以臨時存儲用戶信息。
3.2、Web本地存儲事件監聽
當程序修改localStorage與sessionStorage時將觸發全局事件。
當setItem(),removeItem()或者clear() 方法被調用,並且數據真的發生了改變時,就會觸發storage事件,如果需要進行監聽數據處理,通過以下方法:
window.addEventListener(event,handleEvent, capture)
event:設置成storage
handleEvent:事件處理函數
capture:事件處理順序,一般設置成false,表示采用冒泡方式處理
handleEvent處理事件的函數會接收到一個StorageEvent對象,該對象有以下屬性:
key:被修改的鍵。
oldValue:修改前的值(如果是增加新的鍵值,則該屬性為null)
newValue:修改后的值(如果是刪除鍵值,則該屬性為null)
url/uri:觸發當前存儲事件的頁面的url
注意:storage改變的時候,觸發這個事件會調用所有同域下其他窗口的storage事件,不過它本身觸發storage即當前窗口是不會觸發這個事件的(當然ie這個特例除外,它包含自己本事也會觸發storage事件)
修改d02頁面,監聽值的變化。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>獲得localStorage的值</title> </head> <body> <script type="text/javascript"> console.log(localStorage.price); window.addEventListener("storage",function(obj){ alert(obj.oldValue+","+obj.newValue+","+obj.url); },true); </script> </body> </html>
運行結果如下:

3.3、cookie、sessionStorage、localStorage比較


四、Web SQL Database
Web SQL Database 引入了一套使用 SQL 來操縱客戶端數據庫(client-side database)的 API,這些 API 是異步的(asynchronous),規范中所使用的 SQL 語言為 SQLite。Web SQL Database API 實際上未包含在 HTML 5 規范之中,它是一個獨立的規范,它引入了一套使用 SQL 操作客戶端數據庫的 API,這些 API 有同步的,也有異步的, 同步版本的 API 只在工作線程(Worker Threads)上有用,由於並不是所有的瀏覽器都支持工作線程,一般情況下,都會使用異步 API。兼容情況如下:

Web SQL Database可以讓開發人員使用SQL語句操作客戶端瀏覽器中嵌入的SQLite數據庫 ,給開發人員提供了方便。對於簡單的數據,使用sessionStorage和localStorage能夠很好地完成存取,但是對於處理復雜的關系型數據,它就力不從心了。這也是 HTML 5 的“Web SQLDatabase”API 接口的應用所在。我把它理解成一個Html5環境下可以用Js執行CRUD的Web數據庫
三個核心方法
openDatabase:這個方法使用現有數據庫或創建新數據庫創建數據庫對象。
transaction:這個方法允許我們根據情況控制事務提交或回滾。
executeSql:這個方法用於執行真實的SQL查詢。

4.1、創建數據庫
使用openDatabase創建或打開數據庫,如果存在就打開,如果不存在就創建,語法如下:
openDatabase(a,b,c,d,e);
a).數據庫名稱。
b).版本號 目前為1.0
c).對數據庫的描述
d).設置數據的大小,以Byte為單位
e).回調函數(可省略)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <h2>Web SQL Database</h2> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //數據庫 var db; //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 db=openDatabase("products",1.0,"產品數據庫",1024*1024*3,function(){ log("創建或打開數據庫完成"); }); //顯示消息 function log(info){ $("#msg")[0].innerHTML+=info+"<br/>"; } </script> </body> </html>
運行結果:

4.2、創建表
執行所有的SQL語句都將使用到transaction、executeSql兩個方法,基本語法格式如下:
數據庫對象.transaction(function(tx) { tx.executeSql( "要執行的sql", [參數], function(tx, result) { alert('成功時的回調方法'); }, function(tx, error) { alert('失敗時的回調方法' + error.message); }); });
頁面腳本如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <h2>Web SQL Database</h2> <div> <button onclick="createTable()">創建表</button> </div> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //創建或打開名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 var db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { log("創建數據庫完成"); }); //創建表 function createTable() { db.transaction(function(tx) { tx.executeSql( "create table if not exists goods(id integer primary key autoincrement,name text not null,price double)", [], function(tx, result) { log('創建表成功'); }, function(tx, error) { log('創建表失敗' + error.message); }); }); } //顯示消息 function log(info) { $("#msg")[0].innerHTML += info + "<br/>"; } </script> </body> </html>
運行結果:

當創建成功時,可以發現在出現了兩個表,其中名為sqlite_sequence為自動增長用的序列。
4.3、添加數據
頁面腳本如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <h2>Web SQL Database</h2> <div> <button onclick="createTable()">創建表</button> <fieldset> <legend>商品信息</legend> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <button onclick="insert()">添加</button> </p> </fieldset> </div> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 var db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { log("創建或打開數據庫完成"); }); //創建表 function createTable() { db.transaction(function(tx) { tx.executeSql( "create table if not exists goods(id integer primary key autoincrement,name text not null,price double)", [], function(tx, result) { log('創建表成功'); }, function(tx, error) { log('創建表失敗' + error.message); }); }); } //插入數據 function insert() { db.transaction(function(tx) { tx.executeSql( "insert into goods(name,price) values(?,?)", [$("#name").val(),$("#price").val()], function(tx, result) { log('添加數據成功'); }, function(tx, error) { log('添加數據失敗' + error.message); }); }); } //顯示消息 function log(info) { $("#msg")[0].innerHTML += info + "<br/>"; } </script> </body> </html>
運行結果:

4.4、展示數據
頁面腳本如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <h2>Web SQL Database</h2> <div> <button onclick="createTable()">創建表</button> <table border="1" width="80%" id="tabGoods"> <tr><th>編號</th><th>名稱</th><th>價格</th><th>刪除</th></tr> </table> <fieldset> <legend>商品信息</legend> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <button onclick="insert()">添加</button> </p> </fieldset> </div> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 var db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { log("創建或打開數據庫完成"); }); //展示,加載數據 function select() { //將表格中tr索引大於0的元素刪除 $("#tabGoods tr:gt(0)").remove(); db.transaction(function(tx) { tx.executeSql( "select id,name,price from goods", [], function(tx, result) { for (var i=0;i<result.rows.length;i++) { var tr=$("<tr/>"); $("<td/>").text(result.rows.item(i)["id"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["name"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); var del=$("<a href='#' onclick='del("+result.rows.item(i)["id"]+")' >刪除</a>") $("<td/>").append(del).appendTo(tr); tr.appendTo("#tabGoods"); } }, function(tx, error) { log('創建表失敗' + error.message); }); }); } select(); //創建表 function createTable() { db.transaction(function(tx) { tx.executeSql( "create table if not exists goods(id integer primary key autoincrement,name text not null,price double)", [], function(tx, result) { log('創建表成功'); }, function(tx, error) { log('創建表失敗' + error.message); }); }); } //插入數據 function insert() { db.transaction(function(tx) { tx.executeSql( "insert into goods(name,price) values(?,?)", [$("#name").val(),$("#price").val()], function(tx, result) { log('添加數據成功'); select(); }, function(tx, error) { log('添加數據失敗' + error.message); }); }); } //顯示消息 function log(info) { $("#msg")[0].innerHTML += info + "<br/>"; } </script> </body> </html>
運行結果如下:

4.5、編輯數據
頁面腳本如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <h2>Web SQL Database</h2> <div> <button onclick="createTable()">創建表</button> <table border="1" width="80%" id="tabGoods"> <tr> <th>編號</th> <th>名稱</th> <th>價格</th> <th>刪除</th> </tr> </table> <fieldset> <legend>商品信息</legend> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <input type="hidden" id="goodsId" /> <button onclick="insert()">添加</button> <button onclick="update()">更新</button> </p> </fieldset> </div> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 var db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { log("創建或打開數據庫完成"); }); //展示,加載數據 function select() { //將表格中tr索引大於0的元素刪除 $("#tabGoods tr:gt(0)").remove(); db.transaction(function(tx) { tx.executeSql( "select id,name,price from goods", [], function(tx, result) { for(var i = 0; i < result.rows.length; i++) { var tr = $("<tr/>"); $("<td/>").text(result.rows.item(i)["id"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["name"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); var del = $("<a href='#' onclick='del(" + result.rows.item(i)["id"] + ",this)' >刪除 | </a>") var edit = $("<a href='#' onclick='edit(" + result.rows.item(i)["id"] + ",this)' >修改</a>") $("<td/>").append(del).append(edit).appendTo(tr); tr.appendTo("#tabGoods"); } }, function(tx, error) { log('創建表失敗' + error.message); }); }); } select(); //創建表 function createTable() { db.transaction(function(tx) { tx.executeSql( "create table if not exists goods(id integer primary key autoincrement,name text not null,price double)", [], function(tx, result) { log('創建表成功'); }, function(tx, error) { log('創建表失敗' + error.message); }); }); } //插入數據 function insert() { db.transaction(function(tx) { tx.executeSql( "insert into goods(name,price) values(?,?)", [$("#name").val(), $("#price").val()], function(tx, result) { log('添加數據成功'); select(); }, function(tx, error) { log('添加數據失敗' + error.message); }); }); } //刪除 function del(id, link) { db.transaction(function(tx) { tx.executeSql( "delete from goods where id=?", [id], function(tx, result) { log('刪除成功'); //查找a標簽最近的一個tr父元素,移除 $(link).closest("tr").remove(); }, function(tx, error) { log('刪除失敗' + error.message); }); }); } //編輯 function edit(id) { db.transaction(function(tx) { tx.executeSql( "select id,name,price from goods where id=?", [id], function(tx, result) { $("#name").val(result.rows.item(0)["name"]); $("#price").val(result.rows.item(0)["price"]); $("#goodsId").val(result.rows.item(0)["id"]); log("修改后請保存"); }, function(tx, error) { log('編輯失敗' + error.message); }); }); } //更新 function update() { if($("#goodsId").val()) { db.transaction(function(tx) { tx.executeSql( "update goods set name=?,price=? where id=?", [$("#name").val(), $("#price").val(), $("#goodsId").val()], function(tx, result) { log('更新成功'); select(); $("#goodsId").val(""); }, function(tx, error) { log('更新失敗' + error.message); }); }); } else { log("請選擇要更新的記錄 "); } } //顯示消息 function log(info) { $("#msg")[0].innerHTML += info + "<br/>"; } </script> </body> </html>
運行結果如下:


4.6、刪除數據
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <h2>Web SQL Database</h2> <div> <button onclick="createTable()">創建表</button> <table border="1" width="80%" id="tabGoods"> <tr><th>編號</th><th>名稱</th><th>價格</th><th>刪除</th></tr> </table> <fieldset> <legend>商品信息</legend> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <button onclick="insert()">添加</button> </p> </fieldset> </div> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 var db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { log("創建或打開數據庫完成"); }); //展示,加載數據 function select() { //將表格中tr索引大於0的元素刪除 $("#tabGoods tr:gt(0)").remove(); db.transaction(function(tx) { tx.executeSql( "select id,name,price from goods", [], function(tx, result) { for (var i=0;i<result.rows.length;i++) { var tr=$("<tr/>"); $("<td/>").text(result.rows.item(i)["id"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["name"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); var del=$("<a href='#' onclick='del("+result.rows.item(i)["id"]+",this)' >刪除</a>") $("<td/>").append(del).appendTo(tr); tr.appendTo("#tabGoods"); } }, function(tx, error) { log('創建表失敗' + error.message); }); }); } select(); //創建表 function createTable() { db.transaction(function(tx) { tx.executeSql( "create table if not exists goods(id integer primary key autoincrement,name text not null,price double)", [], function(tx, result) { log('創建表成功'); }, function(tx, error) { log('創建表失敗' + error.message); }); }); } //插入數據 function insert() { db.transaction(function(tx) { tx.executeSql( "insert into goods(name,price) values(?,?)", [$("#name").val(),$("#price").val()], function(tx, result) { log('添加數據成功'); select(); }, function(tx, error) { log('添加數據失敗' + error.message); }); }); } //刪除 function del(id,link) { db.transaction(function(tx) { tx.executeSql( "delete from goods where id=?", [id], function(tx, result) { log('刪除成功'); //查找a標簽最近的一個tr父元素,移除 $(link).closest("tr").remove(); }, function(tx, error) { log('刪除失敗' + error.message); }); }); } //顯示消息 function log(info) { $("#msg")[0].innerHTML += info + "<br/>"; } </script> </body> </html>
運行結果:

4.7、刪除表
刪除表
//創建表 function dropTable() { db.transaction(function(tx) { tx.executeSql( "drop table IF EXISTS goods", [], function(tx, result) { log('刪除表成功'); }, function(tx, error) { log('刪除表失敗' + error.message); }); }); }
運行結果:

4.8、數據庫位置
D:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\databases

4.9、封裝JavaScript
前面的示例中javascript方法都直接暴露在window下,有可能與別的js沖突,可以進行簡單封裝。
簡單對象封裝示例:
var ticker={ n:0, add:function() { this.n++; }, show:function() { alert(this.n); } } ticker.add(); ticker.add(); ticker.show();
運行結果:2
第一次封裝后的代碼,在整個window對象中只暴露dbApp對象,代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Web SQL Database</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<h2>Web SQL Database</h2>
<div>
<button id="btnCreateTable">創建表</button>
<button id="btnDropTable">刪除表</button>
<table border="1" width="80%" id="tabGoods">
<tr>
<th>編號</th>
<th>名稱</th>
<th>價格</th>
<th>刪除</th>
</tr>
</table>
<fieldset>
<legend>商品信息</legend>
<p>
<label for="name">名稱:</label>
<input type="text" id="name" value="" />
</p>
<p>
<label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <input type="hidden" id="goodsId" /> <button id="btnInsert">添加</button> <button id="btnUpdate">更新</button> </p> </fieldset> </div> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義當前應用的對象 var dbApp={ //打開數據庫 openDb:function() { //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 this.db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { this.log("創建或打開數據庫完成"); }); }, //初始化 init:function() { //打開或創建數據庫 this.openDb(); //綁定事件 this.bindEvent(); //展示數據 this.select(); this.log("初始化完成"); }, //綁定事件 bindEvent:function() { //添加事件 $("#btnInsert").click(this.insert); $("#btnUpdate").click(this.update); $("#btnCreateTable").click(this.createTable); $("#btnDropTable").click(this.dropTable); }, //顯示消息 log:function(info) { $("#msg")[0].innerHTML += info + "<br/>"; }, //創建表 createTable:function() { this.db.transaction(function(tx) { tx.executeSql( "create table IF not EXISTS goods(id integer primary key autoincrement,name text not null,price double)", [], function(tx, result) { this.log('創建表成功'); }, function(tx, error) { this.log('創建表失敗' + error.message); }); }); }, //刪除表 dropTable:function() { this.db.transaction(function(tx) { tx.executeSql( "drop table IF EXISTS goods", [], function(tx, result) { this.log('刪除表成功'); }, function(tx, error) { this.log('刪除表失敗' + error.message); }); }); }, //展示,加載數據 select:function() { //將表格中tr索引大於0的元素刪除 $("#tabGoods tr:gt(0)").remove(); this.db.transaction(function(tx) { tx.executeSql( "select id,name,price from goods", [], function(tx, result) { for(var i = 0; i < result.rows.length; i++) { var tr = $("<tr/>"); $("<td/>").text(result.rows.item(i)["id"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["name"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); var del = $("<a href='#' onclick='dbApp.del(" + result.rows.item(i)["id"] + ",this)' >刪除 | </a>") var edit = $("<a href='#' onclick='dbApp.edit(" + result.rows.item(i)["id"] + ",this)' >修改</a>") $("<td/>").append(del).append(edit).appendTo(tr); tr.appendTo("#tabGoods"); } }, function(tx, error) { this.log('創建表失敗' + error.message); }); }); }, //插入數據 insert:function() { //如果insert方法被綁定為事件,則this表示事件發生的對象 dbApp.db.transaction(function(tx) { tx.executeSql( "insert into goods(name,price) values(?,?)", [$("#name").val(), $("#price").val()], function(tx, result) { dbApp.log('添加數據成功'); //刷新 dbApp.select(); }, function(tx, error) { dbApp.log('添加數據失敗' + error.message); }); }); }, //刪除 del:function(id, link) { dbApp.db.transaction(function(tx) { tx.executeSql( "delete from goods where id=?", [id], function(tx, result) { dbApp.log('刪除成功'); //查找a標簽最近的一個tr父元素,移除 $(link).closest("tr").remove(); }, function(tx, error) { dbApp.log('刪除失敗' + error.message); }); }); }, //編輯 edit:function(id) { dbApp.db.transaction(function(tx) { tx.executeSql( "select id,name,price from goods where id=?", [id], function(tx, result) { $("#name").val(result.rows.item(0)["name"]); $("#price").val(result.rows.item(0)["price"]); $("#goodsId").val(result.rows.item(0)["id"]); dbApp.log("修改后請保存"); }, function(tx, error) { dbApp.log('編輯失敗' + error.message); }); }); }, //更新 update:function() { if($("#goodsId").val()) { dbApp.db.transaction(function(tx) { tx.executeSql( "update goods set name=?,price=? where id=?", [$("#name").val(), $("#price").val(), $("#goodsId").val()], function(tx, result) { dbApp.log('更新成功'); dbApp.select(); $("#goodsId").val(""); }, function(tx, error) { dbApp.log('更新失敗' + error.message); }); }); } else { dbApp.log("請選擇要更新的記錄 "); } } }; dbApp.init(); </script> </body> </html>
運行結果:

從上面的代碼可以發現操作數據庫,執行sql的方法存在大量的冗余,可以優化,優化后的代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <h2>Web SQL Database</h2> <div> <button id="btnCreateTable">創建表</button> <button id="btnDropTable">刪除表</button> <table border="1" width="80%" id="tabGoods"> <tr> <th>編號</th> <th>名稱</th> <th>價格</th> <th>刪除</th> </tr> </table> <fieldset> <legend>商品信息</legend> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <input type="hidden" id="goodsId" /> <button id="btnInsert">添加</button> <button id="btnUpdate">更新</button> </p> </fieldset> </div> <h2 id="msg"></h2> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義當前應用的對象 var dbApp={ //打開數據庫 openDb:function() { //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 this.db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { this.log("創建或打開數據庫完成"); }); }, //初始化 init:function() { //打開或創建數據庫 this.openDb(); //綁定事件 this.bindEvent(); //展示數據 this.select(); this.log("初始化完成"); }, //綁定事件 bindEvent:function() { //添加事件 $("#btnInsert").click(this.insert); $("#btnUpdate").click(this.update); $("#btnCreateTable").click(this.createTable); $("#btnDropTable").click(this.dropTable); }, //顯示消息 log:function(info) { $("#msg")[0].innerHTML += info + "<br/>"; }, //執行sql的通用方法 result.rowsAffected 影響行數 //callback執行成功時的回調方法 exeSql:function(sql,title,param,callback) { title=title||"操作"; this.db.transaction(function(tx) { tx.executeSql( sql, param||[], function(tx, result) { dbApp.log(title+'成功'); if(callback){ //如果有參數 callback(result); } }, function(tx, error) { dbApp.log(title+'失敗' + error.message); }); }); }, //創建表 createTable:function() { dbApp.exeSql("create table IF not EXISTS goods(id integer primary key autoincrement,name text not null,price double)","創建表"); }, //刪除表 dropTable:function() { dbApp.exeSql("drop table IF EXISTS goods","刪除表"); }, //展示,加載數據 select:function() { dbApp.exeSql("select id,name,price from goods","查詢",[],function(result) { //將表格中tr索引大於0的元素刪除 $("#tabGoods tr:gt(0)").remove(); for(var i = 0; i < result.rows.length; i++) { var tr = $("<tr/>"); $("<td/>").text(result.rows.item(i)["id"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["name"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); var del = $("<a href='#' onclick='dbApp.del(" + result.rows.item(i)["id"] + ",this)' >刪除 | </a>") var edit = $("<a href='#' onclick='dbApp.edit(" + result.rows.item(i)["id"] + ",this)' >修改</a>") $("<td/>").append(del).append(edit).appendTo(tr); tr.appendTo("#tabGoods"); } }); }, //插入數據 insert:function() { //如果insert方法被綁定為事件,則this表示事件發生的對象 dbApp.exeSql("insert into goods(name,price) values(?,?)","添加",[$("#name").val(), $("#price").val()],function(){ dbApp.select(); }); }, //刪除 del:function(id, link) { dbApp.exeSql("delete from goods where id=?","刪除",[id],function(result){ //查找a標簽最近的一個tr父元素,移除 $(link).closest("tr").remove(); }); }, //編輯 edit:function(id) { dbApp.exeSql("select id,name,price from goods where id=?","編輯",[id],function(result) { $("#name").val(result.rows.item(0)["name"]); $("#price").val(result.rows.item(0)["price"]); $("#goodsId").val(result.rows.item(0)["id"]); dbApp.log("修改后請保存"); }); }, //更新 update:function() { if($("#goodsId").val()) { dbApp.exeSql("update goods set name=?,price=? where id=?","更新",[$("#name").val(), $("#price").val(), $("#goodsId").val()],function(result) { dbApp.select(); $("#goodsId").val(""); }); } else { dbApp.log("請選擇要更新的記錄 "); } } }; dbApp.init(); </script> </body> </html>
運行結果:

4.10、美化頁面
在原頁面的基礎上增加css樣式,添加樣式后的頁面腳本如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web SQL Database</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <style type="text/css"> * { margin: 0; padding: 0; font-family: "microsoft yahei"; } #container{ padding: 10px; font-size: 14px; } #container a{ color: #fff; text-decoration: none; margin-right: 5px; } #container a:hover{ color:orangered; } button,a{ border: 0; height: 22px; line-height: 22px; border-radius: 3px; padding:0 10px; background: dodgerblue; color: white; } button:hover{ background: orangered; } #container h2{ height: 60px; } html #tabGoods{ width:100%; margin: 15px 0; border: 2px solid #0062CC; } #tabGoods,#tabGoods td,#tabGoods th { border: 1px solid #0062CC; border-collapse: collapse; } #tabGoods td,#tabGoods th{ padding: 5px 0 5px 5px; } #fieldsetForm{ width: 400px; padding: 10px; border-radius: 10px; border: 2px solid #0062CC; } #fieldsetForm p{ padding: 10px; } #msg{ font-size: 16px; font-weight: normal; height: 100px; overflow: auto; margin-top: 10px; } </style> </head> <body> <div id="container"> <h2>Web SQL Database</h2> <button id="btnCreateTable">創建表</button> <button id="btnDropTable">刪除表</button> <table id="tabGoods"> <tr> <th>編號</th> <th>名稱</th> <th>價格</th> <th>刪除</th> </tr> </table> <fieldset id="fieldsetForm"> <legend>商品信息</legend> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <input type="hidden" id="goodsId" /> <button id="btnInsert">添加</button> <button id="btnUpdate">更新</button> </p> </fieldset> <h2 id="msg"></h2> </div> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義當前應用的對象 var dbApp = { //打開數據庫 openDb: function() { //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 this.db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { this.log("創建或打開數據庫完成"); }); }, //初始化 init: function() { //打開或創建數據庫 this.openDb(); //綁定事件 this.bindEvent(); //展示數據 this.select(); this.log("初始化完成"); }, //綁定事件 bindEvent: function() { //添加事件 $("#btnInsert").click(this.insert); $("#btnUpdate").click(this.update); $("#btnCreateTable").click(this.createTable); $("#btnDropTable").click(this.dropTable); }, //顯示消息 log: function(info) { $("#msg")[0].innerHTML += info + "<br/>"; }, //執行sql的通用方法 result.rowsAffected 影響行數 //callback執行成功時的回調方法 exeSql: function(sql, title, param, callback) { title = title || "操作"; this.db.transaction(function(tx) { tx.executeSql( sql, param || [], function(tx, result) { dbApp.log(title + '成功'); if(callback) { //如果有參數 callback(result); } }, function(tx, error) { dbApp.log(title + '失敗' + error.message); }); }); }, //創建表 createTable: function() { dbApp.exeSql("create table IF not EXISTS goods(id integer primary key autoincrement,name text not null,price double)", "創建表"); }, //刪除表 dropTable: function() { dbApp.exeSql("drop table IF EXISTS goods", "刪除表"); }, //展示,加載數據 select: function() { dbApp.exeSql("select id,name,price from goods", "查詢", [], function(result) { //將表格中tr索引大於0的元素刪除 $("#tabGoods tr:gt(0)").remove(); for(var i = 0; i < result.rows.length; i++) { var tr = $("<tr/>"); $("<td/>").text(result.rows.item(i)["id"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["name"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); var del = $("<a href='#' onclick='dbApp.del(" + result.rows.item(i)["id"] + ",this)' >刪除</a> ") var edit = $("<a href='#' onclick='dbApp.edit(" + result.rows.item(i)["id"] + ",this)' >修改</a>") $("<td/>").append(del).append(edit).appendTo(tr); tr.appendTo("#tabGoods"); } }); }, //插入數據 insert: function() { //如果insert方法被綁定為事件,則this表示事件發生的對象 dbApp.exeSql("insert into goods(name,price) values(?,?)", "添加", [$("#name").val(), $("#price").val()], function() { dbApp.select(); }); }, //刪除 del: function(id, link) { dbApp.exeSql("delete from goods where id=?", "刪除", [id], function(result) { //查找a標簽最近的一個tr父元素,移除 $(link).closest("tr").remove(); }); }, //編輯 edit: function(id) { dbApp.exeSql("select id,name,price from goods where id=?", "編輯", [id], function(result) { $("#name").val(result.rows.item(0)["name"]); $("#price").val(result.rows.item(0)["price"]); $("#goodsId").val(result.rows.item(0)["id"]); dbApp.log("修改后請保存"); }); }, //更新 update: function() { if($("#goodsId").val()) { dbApp.exeSql("update goods set name=?,price=? where id=?", "更新", [$("#name").val(), $("#price").val(), $("#goodsId").val()], function(result) { dbApp.select(); $("#goodsId").val(""); }); } else { dbApp.log("請選擇要更新的記錄 "); } } }; dbApp.init(); </script> </body> </html>
運行結果:

五、移動端打包與運行
5.1、在手機端直接訪問Web站點
將手機與電腦連接到同一個網段,比如可以使用wifi
查看本機ip地址,有時需要將本地連接禁用,查看ip地址的指令是ipconfig
在手機端使用瀏覽器查看結果如下:

5.2、打包成app安裝運行
這里使用HBuilder打包成apk的安裝包,安裝打包結果如下:


5.3、套用移動端UI框架
這里使用HBuilder內置的MUI為例,新增d06.html,頁面腳本如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>淘水果</title> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <!--標准mui.css--> <link rel="stylesheet" href="css/mui.min.css"> <!--App自定義的css--> <link rel="stylesheet" type="text/css" href="css/app.css" /> <style> .title { margin: 20px 15px 10px; color: #6d6d72; font-size: 15px; } .oa-contact-cell.mui-table .mui-table-cell { padding: 11px 0; vertical-align: middle; } .oa-contact-cell { position: relative; margin: -11px 0; } .oa-contact-avatar { width: 75px; } .oa-contact-avatar img { border-radius: 50%; } .oa-contact-content { width: 100%; } .oa-contact-name { margin-right: 20px; } .oa-contact-name, oa-contact-position { float: left; } </style> </head> <body> <header class="mui-bar mui-bar-nav"> <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> <h1 class="mui-title">淘水果</h1> </header> <nav class="mui-bar mui-bar-tab"> <a class="mui-tab-item mui-active" href="#tabbar"> <span class="mui-icon mui-icon-home"></span> <span class="mui-tab-label">暢銷水果</span> </a> <a class="mui-tab-item" href="#tabbar-with-chat"> <span class="mui-icon mui-icon-email"><span class="mui-badge">9</span></span> <span class="mui-tab-label">新貨上架</span> </a> <a class="mui-tab-item" href="#tabbar-with-contact"> <span class="mui-icon mui-icon-contact"></span> <span class="mui-tab-label">收款</span> </a> <a class="mui-tab-item" href="#tabbar-with-map"> <span class="mui-icon mui-icon-gear"></span> <span class="mui-tab-label">發貨</span> </a> </nav> <div class="mui-content"> <div id="tabbar" class="mui-control-content mui-active"> <div id="slider" class="mui-slider"> <div class="mui-slider-group mui-slider-lhttp://127.0.0.1:8020/HTML5_2_1/d06.html#oop"> <!-- 額外增加的一個節點(循環輪播:第一個節點是最后一張輪播) --> <div class="mui-slider-item mui-slider-item-duplicate"> <a href="#"> <img src="images/yuantiao.jpg"> </a> </div> <!-- 第一張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/shuijiao.jpg"> </a> </div> <!-- 第二張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/muwu.jpg"> </a> </div> <!-- 第三張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/cbd.jpg"> </a> </div> <!-- 第四張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/yuantiao.jpg"> </a> </div> <!-- 額外增加的一個節點(循環輪播:最后一個節點是第一張輪播) --> <div class="mui-slider-item mui-slider-item-duplicate"> <a href="#"> <img src="images/shuijiao.jpg"> </a> </div> </div> <div class="mui-slider-indicator"> <div class="mui-indicator mui-active"></div> <div class="mui-indicator"></div> <div class="mui-indicator"></div> <div class="mui-indicator"></div> </div> </div> <ul class="mui-table-view mui-table-view-chevron" id="goodsList"> </ul> </div> <div id="tabbar-with-chat" class="mui-control-content"> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <input type="hidden" id="goodsId" /> <button id="btnInsert">添加</button> <button id="btnUpdate">更新</button> </p> </div> <div id="tabbar-with-contact" class="mui-control-content"> <div class="title">這是div模式選項卡中的第3個子頁面,該頁面展示一個通訊錄示例.</div> <ul class="mui-table-view mui-table-view-striped mui-table-view-condensed"> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">葉文潔</h4> <span class="oa-contact-position mui-h6">董事長</span> </div> <p class="oa-contact-email mui-h6"> yewenjie@sina.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">艾AA</h4> <span class="oa-contact-position mui-h6">總經理</span> </div> <p class="oa-contact-email mui-h6"> aaa@163.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">羅輯</h4> <span class="oa-contact-position mui-h6">員工</span> </div> <p class="oa-contact-email mui-h6"> luoji@126.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">雲天明</h4> <span class="oa-contact-position mui-h6">員工</span> </div> <p class="oa-contact-email mui-h6"> ytm@163.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">史強</h4> <span class="oa-contact-position mui-h6">員工</span> </div> <p class="oa-contact-email mui-h6"> shiqiang@gmail.com </p> </div> </div> </div> </li> </ul> </div> <div id="tabbar-with-map" class="mui-control-content"> <div class="title">這是div模式選項卡中的第4個子頁面,該頁面展示一個常見的設置示例.</div> <ul class="mui-table-view"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 新消息通知 </a> </li> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 隱私 </a> </li> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 通用 </a> </li> </ul> <ul class="mui-table-view" style="margin-top: 25px;"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 關於mui </a> </li> </ul> <ul class="mui-table-view" style="margin-top: 25px;"> <li class="mui-table-view-cell"> <a style="text-align: center;color: #FF3B30;"> 退出登錄 </a> </li> </ul> </div> </div> </body> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/mui.min.js"></script> <script> //定義當前應用的對象 var dbApp = { //打開數據庫 openDb: function() { //創建名稱為products,版本為1.0,描述為產品數據庫,3M大小的數據庫 this.db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { this.log("創建或打開數據庫完成"); }); }, //初始化 init: function() { //打開或創建數據庫 this.openDb(); //綁定事件 this.bindEvent(); //展示數據 this.select(); this.log("初始化完成"); }, //綁定事件 bindEvent: function() { //添加事件 $("#btnInsert").click(this.insert); $("#btnUpdate").click(this.update); $("#btnCreateTable").click(this.createTable); $("#btnDropTable").click(this.dropTable); }, //顯示消息 log: function(info) { mui.toast(info); }, //執行sql的通用方法 result.rowsAffected 影響行數 //callback執行成功時的回調方法 exeSql: function(sql, title, param, callback) { title = title || "操作"; this.db.transaction(function(tx) { tx.executeSql( sql, param || [], function(tx, result) { dbApp.log(title + '成功'); if(callback) { //如果有參數 callback(result); } }, function(tx, error) { dbApp.log(title + '失敗' + error.message); }); }); }, //創建表 createTable: function() { dbApp.exeSql("create table IF not EXISTS goods(id integer primary key autoincrement,name text not null,price double)", "創建表"); }, //刪除表 dropTable: function() { dbApp.exeSql("drop table IF EXISTS goods", "刪除表"); }, //展示,加載數據 select: function() { dbApp.exeSql("select id,name,price from goods", "查詢", [], function(result) { //將表格中tr索引大於0的元素刪除 $("#goodsList li").remove(); for(var i = 0; i < result.rows.length; i++) { var tr = $("<li class='mui-table-view-cell mui-media'><a class='mui-navigate-right'><img class='mui-media-object mui-pull-left' src='images/cbd.jpg'><div class='mui-media-body'>" + result.rows.item(i)["name"] + "<p class='mui-ellipsis'>新鮮好吃的水果,僅售:" + result.rows.item(i)["price"] + "/斤</p></div></a></li>") tr.appendTo("#goodsList"); } mui.init({ swipeBack: true //啟用右滑關閉功能 }); }); }, //插入數據 insert: function() { //如果insert方法被綁定為事件,則this表示事件發生的對象 dbApp.exeSql("insert into goods(name,price) values(?,?)", "添加", [$("#name").val(), $("#price").val()], function() { dbApp.select(); }); }, //刪除 del: function(id, link) { dbApp.exeSql("delete from goods where id=?", "刪除", [id], function(result) { //查找a標簽最近的一個tr父元素,移除 $(link).closest("tr").remove(); }); }, //編輯 edit: function(id) { dbApp.exeSql("select id,name,price from goods where id=?", "編輯", [id], function(result) { $("#name").val(result.rows.item(0)["name"]); $("#price").val(result.rows.item(0)["price"]); $("#goodsId").val(result.rows.item(0)["id"]); dbApp.log("修改后請保存"); }); }, //更新 update: function() { if($("#goodsId").val()) { dbApp.exeSql("update goods set name=?,price=? where id=?", "更新", [$("#name").val(), $("#price").val(), $("#goodsId").val()], function(result) { dbApp.select(); $("#goodsId").val(""); }); } else { dbApp.log("請選擇要更新的記錄 "); } } }; dbApp.init(); </script> </html>
打包運行后的結果如下:


