B/S架構的應用大量的信息存儲在服務器端,客戶端經過請求響應的方式從服務器得到數據,這樣集中存儲也會給服務器帶來相應的壓力,有些數據能夠直接存儲在客戶端,傳統的Web技術中會使用Cookie,但Cookie有一些缺點,爲了說明這個缺點咱們先看看當提交表單時會有那些信息會被瀏覽器收集後發送到服務器。javascript
1)、帶name的可用表單元素css
2)、urlhtml
3)、客戶端請求頭部信息java
4)、cookiejquery
<%@ 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>
運行結果:git
服務器在響應頭部中聲明要求客戶端瀏覽器指定設置cookie color=blue的工做,且指定了過時時間,會將cookie信息記錄在本地,查看結果以下:github
當提交信息給服務器時cookie將收集後返回服務器,同時也會將url、帶name可用的表單及請求頭部信息如user-agent等,結果以下:web
顧名思義客戶端本地存儲就是將信息存儲在客戶端電腦上,cookie就是一種典型的傳統客戶端存儲,長期以來本地存儲能力一直是桌面應用區別於Web應用的一個主要優點,做爲Web應用程序而言,新一代的HTML標準對數據的本地存儲提出了更高的要求。傳統的Web數據存儲方式一直來使用的是Cookie,但Cookie有如下缺陷:sql
a)、cookie會被附加在每一個HTTP請求中,因此無形中增長了流量。
b)、因爲在HTTP請求中的cookie是明文傳遞的,因此安全性成問題。
c)、Cookie的大小限制在4 KB左右,容量達不到要求。chrome
HTML5中的Web Storage,稱爲Web本地存儲,在Web客戶端儲存數據的功能,用鍵值對的形式保存數據,曾經屬於HTML5的規範,目前已經被獨立出來造成單獨的規範體系。本地存儲優點:
a)、統一的標準,兼容性高(IE八、各大瀏覽器支持)
b)、數據存儲量大
c)、無需安裝插件
d)、減小網絡流量
e)、更加適合移動端
HTML5 提供了四種在客戶端存儲數據的新方法,即localStorage 、sessionStorage、globalStorage、Web Sql Database。 前面三個適用於存儲較少的數據,而Web Sql Database適用於存儲大型的,複雜的數據,我習慣把前面的三個稱之爲小存儲。 IE八、Firefox3.六、Chrome五、Safari四、Opera10,事實證實各個瀏覽器在API方面的實現基本上一致,存在必定的兼容性問題,但不影響正常使用。
在chrome瀏覽器中可使用開發者工具查看到各類不一樣的本地存儲方式,以下圖所示:
Web SQL Database 和 Indexed Database 都是在客戶端存儲大量結構化數據的解決方案。Web SQL Database 實現了傳統的基於 SQL 語句的數據庫操做,而 Indexed Database 實現了 NoSQL 的存儲方式。
localStorage:將數據保存在客戶端本地的硬件設備(一般指硬盤,但也能夠是其餘硬件設備)中,即便瀏覽器被關閉了,該數據仍然存在,下次打開瀏覽器訪問網站時仍然能夠繼續使用。
代碼:
<script type="text/javascript">
//添加
function Add() {
localStorage.name = "小明";
localStorage.setItem("sex", "男");
localStorage["age"] = 23;
}
</script>
運行結果以下:
代碼:
//取值 function Get() { var msg = document.getElementById("msg"); msg.innerHTML += localStorage.name+"<br/>"+ localStorage["sex"]+"<br/>"+ localStorage.getItem("age"); }
運行結果:
代碼:
//修改 function Update() { localStorage.name = "小成"; //若是不存在就添加,若是存在就修改 localStorage.setItem("sex", "男"); localStorage["age"] = 20; }
運行結果:
//刪除 function Delete() { //刪除單個 localStorage.removeItem("name"); } function DeleteAll() { //刪除所有 localStorage.clear(); }
結果:
完整代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Local Storage本地存儲</title> <script type="text/javascript"> //添加 function Add() { localStorage.name = "小明"; localStorage.setItem("sex", "男"); localStorage["age"] = 23; } //取值 function Get() { var msg = document.getElementById("msg"); msg.innerHTML += localStorage.name+"<br/>"+ localStorage["sex"]+"<br/>"+ localStorage.getItem("age")+"<br/>"; } //修改 function Update() { localStorage.name = "小成"; //若是不存在就添加,若是存在就修改 localStorage.setItem("sex", "男"); localStorage["age"] = 20; } //刪除 function Delete() { //刪除單個 localStorage.removeItem("name"); } function DeleteAll() { //刪除所有 localStorage.clear(); } </script> </head> <body> <input type="button" name="btnAdd" id="btnAdd" value="添加" onclick="Add()" /> <input type="button" name="btnGet" id="btnGet" value="取值" onclick="Get()" /> <input type="button" name="btnUpdate" id="btnUpdate" value="修改" onclick="Update()" /> <input type="button" name="btnDelete" id="btnDelete" value="刪除單個" onclick="Delete()" /> <input type="button" name="btnDeleteAll" id="btnDeleteAll" value="刪除所有" onclick="DeleteAll()" /> <a href="d02.html" target="_blank">d02</a> <h3 id="msg"></h3> </body> </html>
當關閉瀏覽器,下次再打開時,值仍然存在。能夠跨頁面,不能跨域。咱們在d01頁面中添加了值,在d02頁面中仍然能夠訪問,在整個同域下均可以訪問。
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
全部須要將少許(不超過4M)數據存儲在客戶端的需求都適用,如密碼,用戶偏好(profile)等
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登陸</title> <style type="text/css"> body { background: #C0C0C0; } p { font-size: 11pt; } fieldset { background: darkseagreen; border: 2px ridge gray; border-radius: 8px; width: 500px; margin: 0 auto; padding: 15px 50px 15px 50px; } #btnLogin { width: 60px; height: 30px; color: white; font-size: 13pt; background: gray; border-radius: 5px; } #btnLogin:hover { background: darkseagreen; cursor: pointer; } </style> </head> <body> <fieldset> <legend>用戶登陸</legend> <p>用戶名:<input type="text" name="txtLoginName" id="txtLoginName" value="" placeholder="請輸入用戶名" /></p> <p> 密碼:<input type="password" name="txtPwd" id="txtPwd" value="" placeholder="請輸入密碼" /></p> <p>記住密碼:<input type="checkbox" name="chkRemeber" id="chkRemeber" value="" /></p> <p><input type="button" name="" id="btnLogin" value="登陸" onclick="login()" /></p> <p>登陸次數:<label id=lblcount></label></p> </fieldset> </body> <script type="text/javascript"> if(localStorage.count == "NaN") { localStorage.count = 0; } if(localStorage.loginname != null) { document.getElementById("txtLoginName").value = localStorage.loginname; if(localStorage.pwd != null) { document.getElementById("txtPwd").value = localStorage.pwd; } } function login() { localStorage.loginname = document.getElementById("txtLoginName").value; var chk = document.getElementById("chkRemeber"); if(chk.checked) { localStorage.pwd = document.getElementById("txtPwd").value; } localStorage.count = (parseInt(localStorage.count) + 1); document.getElementById("lblcount").innerHTML = localStorage.count; window.location.href = "index.html"; } </script> </html>
運行結果:
將數據臨時保存在客戶端session對象中。session對象就是會話對象,session中存儲的數據獨立於每一個客戶,該數據會隨着瀏覽器的關閉而消失。
sessionStorage的操做api與localStorage基本同樣,在不手動清除的狀況下localStorage永久保存,而sessionStorage只是臨時暫存。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>sessionStorage本地存儲</title> <script type="text/javascript"> //添加 function Add() { sessionStorage.name = "小明"; sessionStorage.setItem("sex", "男"); sessionStorage["age"] = 23; } //取值 function Get() { var msg = document.getElementById("msg"); msg.innerHTML += sessionStorage.name+"<br/>"+ sessionStorage["sex"]+"<br/>"+ sessionStorage.getItem("age"); } //修改 function Update() { sessionStorage.name = "小紅"; sessionStorage.setItem("sex", "女"); sessionStorage["age"] = 21; } //刪除 function Delete() { //刪除單個 sessionStorage.removeItem("name"); } function DeleteAll() { //刪除所有 sessionStorage.clear(); } </script> </head> <body> <input type="button" name="btnAdd" id="btnAdd" value="添加" onclick="Add()" /> <input type="button" name="btnGet" id="btnGet" value="取值" onclick="Get()" /> <input type="button" name="btnUpdate" id="btnUpdate" value="修改" onclick="Update()" /> <input type="button" name="btnDelete" id="btnDelete" value="刪除單個" onclick="Delete()" /> <input type="button" name="btnDeleteAll" id="btnDeleteAll" value="刪除所有" onclick="DeleteAll()" /> <a href="d04.html" target="_blank">d02</a> <h3 id="msg"></h3> </body> </html>
運行結果:
能夠實如今頁面間傳值,好比能夠臨時存儲用戶信息。
當程序修改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>
運行結果以下:
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查詢。
使用openDatabase建立或打開數據庫,若是存在就打開,若是不存在就建立,語法以下:
openDatabase(a,b,c,d,e);
a).數據庫名稱。
b).版本號 目前爲1.0
c).對數據庫的描述
d).設置數據的大小,以Byte爲單位
e).回調函數(可省略)
//建立數據庫:Books var db = openDatabase("Books", 1.0, "圖書", 1024 * 1024 * 3, function() { if(db) log("建立數據庫成功!"); });
//建立表 function createTable() { db.transaction(function(tx) { tx.executeSql("create table if not exists book(id integer primary key autoincrement,bookname text,price double,publish text)", [], function(tx, result) { log("建立表book成功!"); }, function(tx, error) { log("建立失敗!" + error.Message) }); }); }
//刪除表 function dropTable() { db.transaction(function(tx) { tx.executeSql("drop table book", [], function(tx, result) { log("刪除表book成功!"); }, function(tx, error) { log("刪除失敗!" + error.Message) }); }); }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web Database 的操做</title> </head> <body> <button onclick="createTable()" value="">建立表</button> <button onclick="dropTable()" value="">刪除表</button> <table border="1" cellspacing="0" cellpadding="0" id=tab_book width="98%" style="text-align: center;"> <tr> <th>編號</th> <th>書名</th> <th>價格</th> <th>出版社</th> <th>刪除</th> <th>編輯</th> </tr> </table> <fieldset> <legend>添加數據</legend> <input type="hidden" name="hidid" id="hidid" value="" /> <p><label for="bookname"> 書名:</label><input type="text" name="bookname" id="bookname" value="" /></p> <p><label for="price"> 價格:</label><input type="text" name="price" id="price" value="" /></p> <p><label for="publish">出版社:</label><input type="text" name="publish" id="publish" value="" /> <p><input type="button" name="add" id="add" value="添加" onclick="insert()" /> <input type="button" name="update" id="update" value="修改" onclick="update()" /></p> </fieldset> <h4 id="msg"></h4> <script src="js/jquery-1.10.2.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //建立數據庫:Books var db = openDatabase("Books", 1.0, "圖書", 1024 * 1024 * 3, function() { if(db) log("建立數據庫成功!"); }); //建立表 function createTable() { db.transaction(function(tx) { tx.executeSql("create table if not exists book(id integer primary key autoincrement,bookname text,price double,publish text)", [], function(tx, result) { log("建立表book成功!"); }, function(tx, error) { log("建立失敗!" + error.Message) }); }); } //刪除表 function dropTable() { db.transaction(function(tx) { tx.executeSql("drop table book", [], function(tx, result) { log("刪除表book成功!"); }, function(tx, error) { log("刪除失敗!" + error.Message) }); }); } //添加數據 function insert() { db.transaction(function(tx) { tx.executeSql("insert into book(bookname ,price ,publish) values(?,?,?)", [$("#bookname").val(), $("#price").val(), $("#publish").val()], function(tx, result) { log("添加數據成功!"); show(); }, function(tx, error) { log("添加數據失敗!" + error.Message) }); }); } show(); //顯示數據 function show() { $("#tab_book tr:gt(0)").remove(); db.transaction(function(tx) { tx.executeSql("select id,bookname,price,publish from book", [], 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)["bookname"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["publish"]).appendTo(tr); var del = $("<a href='#' onclick='del(" + result.rows.item(i)['id'] + ",this)'>刪除</a>"); var audit = $("<a href='#' onclick='edit(" + result.rows.item(i)['id'] + ",this)'>編輯</a>"); $("<td/>").append(del).appendTo(tr); $("<td/>").append(audit).appendTo(tr); tr.appendTo("#tab_book"); } }, function(tx, error) { log("查詢數據失敗!" + error.Message) }); }); } //刪除數據 function del(id, link) { db.transaction(function(tx) { tx.executeSql("delete from book where id=?", [id], function(tx, result) { log("刪除數據成功!"); $(link).closest("tr").remove(); }, function(tx, error) { log("刪除數據失敗!" + error.Message) }); }); } //編輯數據 function edit(id) { db.transaction(function(tx) { tx.executeSql("select id,bookname,price,publish from book where id=?", [id], function(tx, result) { $("#bookname").val(result.rows.item(0)["bookname"]); $("#price").val(result.rows.item(0)["price"]); $("#publish").val(result.rows.item(0)["publish"]); $("#hidid").val(result.rows.item(0)["id"]); }, function(tx, error) { log("編輯數據失敗!" + error.Message) }); }); } //修改數據 function update() { db.transaction(function(tx) { tx.executeSql("update book set bookname=?,price=? ,publish=? where id=?", [$("#bookname").val(), $("#price").val(), $("#publish").val(), $("#hidid").val()], function(tx, result) { log("修改數據成功!"); show(); }, function(tx, error) { log("修改數據失敗!" + error.Message) }); }); } //顯示信息 function log(msg) { $("#msg")[0].innerHTML += msg; } </script> </body> </html>
結果頁面展現:
D:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\databases
前面的示例中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 Database 的操做</title> </head> <body> <div> <button value="" id="btnCreateTable">建立表</button> <button value="" id="btnDropTable">刪除表</button> <table border="1" cellspacing="0" cellpadding="0" id=tab_book width="98%" style="text-align: center;"> <tr> <th>編號</th> <th>書名</th> <th>價格</th> <th>出版社</th> <th>刪除</th> <th>編輯</th> </tr> </table> <fieldset> <legend>添加數據</legend> <input type="hidden" name="hidid" id="hidid" value="" /> <p><label for="bookname"> 書名:</label><input type="text" name="bookname" id="bookname" value="" /></p> <p><label for="price"> 價格:</label><input type="text" name="price" id="price" value="" /></p> <p><label for="publish">出版社:</label><input type="text" name="publish" id="publish" value="" /> <p><input type="button" name="btnAdd" id="btnAdd" value="添加" /> <input type="button" name="btnUpdate" id="btnUpdate" value="修改" /></p> </fieldset> <h4 id="msg"></h4> </div> <script src="js/jquery-1.10.2.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //[封裝一:]封裝js var appDb = { //打開數據庫 opendb: function() { this.db=openDatabase("Books", 1.0, "圖書", 1024 * 1024 * 3, function() { if(db) appDb.log("建立數據庫成功!"); }); }, //初始化 init: function() { this.opendb(); this.bindEvent(); this.show(); appDb.log("初始化成功!"); }, //綁定事件 bindEvent:function(){ $("#btnCreateTable").click(appDb.createTable); $("#btnDropTable").click(appDb.dropTable); $("#btnAdd").click(appDb.insert); $("#btnUpdate").click(appDb.update); }, //建立表 createTable: function() { appDb.db.transaction(function(tx) { tx.executeSql("create table if not exists book(id integer primary key autoincrement,bookname text,price double,publish text)", [], function(tx, result) { appDb.log("建立表book成功!"); }, function(tx, error) { appDb.log("建立失敗!" + error.Message) }); }); }, //刪除表 dropTable: function() { appDb.db.transaction(function(tx) { tx.executeSql("drop table book", [], function(tx, result) { appDb.log("刪除表book成功!"); }, function(tx, error) { appDb.log("刪除失敗!" + error.Message) }); }); }, //添加數據 insert: function() { appDb.db.transaction(function(tx) { tx.executeSql("insert into book(bookname ,price ,publish) values(?,?,?)", [$("#bookname").val(), $("#price").val(), $("#publish").val()], function(tx, result) { appDb.log("添加數據成功!"); appDb.show(); }, function(tx, error) { appDb.log("添加數據失敗!" + error.Message) }); }); }, //顯示數據 show: function() { $("#tab_book tr:gt(0)").remove(); appDb.db.transaction(function(tx) { tx.executeSql("select id,bookname,price,publish from book", [], 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)["bookname"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["publish"]).appendTo(tr); var del = $("<a href='#' onclick='appDb.del(" + result.rows.item(i)['id'] + ",this)'>刪除</a>"); var audit = $("<a href='#' onclick='appDb.edit(" + result.rows.item(i)['id'] + ",this)'>編輯</a>"); $("<td/>").append(del).appendTo(tr); $("<td/>").append(audit).appendTo(tr); tr.appendTo("#tab_book"); } }, function(tx, error) { appDb.log("查詢數據失敗!" + error.Message) }); }); }, //刪除數據 del: function(id, link) { appDb.db.transaction(function(tx) { tx.executeSql("delete from book where id=?", [id], function(tx, result) { appDb.log("刪除數據成功!"); $(link).closest("tr").remove(); }, function(tx, error) { appDb.log("刪除數據失敗!" + error.Message) }); }); }, //編輯數據 edit: function(id) { appDb.db.transaction(function(tx) { tx.executeSql("select id,bookname,price,publish from book where id=?", [id], function(tx, result) { $("#bookname").val(result.rows.item(0)["bookname"]); $("#price").val(result.rows.item(0)["price"]); $("#publish").val(result.rows.item(0)["publish"]); $("#hidid").val(result.rows.item(0)["id"]); }, function(tx, error) { appDb.log("編輯數據失敗!" + error.Message) }); }); }, //修改數據 update: function() { if($("#hidid").val()) { appDb.db.transaction(function(tx) { tx.executeSql("update book set bookname=?,price=? ,publish=? where id=?", [$("#bookname").val(), $("#price").val(), $("#publish").val(), $("#hidid").val()], function(tx, result) { appDb.log("修改數據成功!"); appDb.show(); $("#hidid").val(""); }, function(tx, error) { appDb.log("修改數據失敗!" + error.Message) }); }); } else { appDb.log("請先選擇要操做的記錄!") } }, //顯示信息 log: function(msg) { $("#msg")[0].innerHTML += msg+"<br/>"; } } appDb.init(); </script> </body> </html>
從上面的代碼能夠發現操做數據庫,執行sql的方法存在大量的冗餘,能夠優化,優化後的代碼以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web Database 的操做</title> </head> <body> <div> <button value="" id="btnCreateTable">建立表</button> <button value="" id="btnDropTable">刪除表</button> <table border="1" cellspacing="0" cellpadding="0" id=tab_book width="98%" style="text-align: center;"> <tr> <th>編號</th> <th>書名</th> <th>價格</th> <th>出版社</th> <th>刪除</th> <th>編輯</th> </tr> </table> <fieldset> <legend>添加數據</legend> <input type="hidden" name="hidid" id="hidid" value="" /> <p><label for="bookname"> 書名:</label><input type="text" name="bookname" id="bookname" value="" /></p> <p><label for="price"> 價格:</label><input type="text" name="price" id="price" value="" /></p> <p><label for="publish">出版社:</label><input type="text" name="publish" id="publish" value="" /> <p><input type="button" name="btnAdd" id="btnAdd" value="添加" /> <input type="button" name="btnUpdate" id="btnUpdate" value="修改" /></p> </fieldset> <h4 id="msg"></h4> </div> <script src="js/jquery-1.10.2.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //[封裝二:]封裝js var appDb = { //打開數據庫 opendb: function() { this.db = openDatabase("Books", 1.0, "圖書", 1024 * 1024 * 3, function() { if(db) appDb.log("建立數據庫成功!"); }); }, //初始化 init: function() { this.opendb(); this.show(); this.bindEvent(); appDb.log("初始化成功!"); }, //綁定事件 bindEvent: function() { $("#btnCreateTable").click(appDb.createTable); $("#btnDropTable").click(appDb.dropTable); $("#btnAdd").click(appDb.insert); $("#btnUpdate").click(appDb.update); }, //通用sql exeSql: function(sql, title, param, callback) { title || 操做; appDb.db.transaction(function(tx) { tx.executeSql(sql, param || [], function(tx, result) { appDb.log(title + "成功!"); if(callback) callback(result); }, function(tx, error) { appDb.log(title + "失敗!" + error.Message) }); }); }, //建立表 createTable: function() { appDb.exeSql("create table if not exists book(id integer primary key autoincrement,bookname text,price double,publish text)", "建立表"); }, //刪除表 dropTable: function() { appDb.exeSql("drop table book", "刪除表"); }, //添加數據 insert: function() { appDb.exeSql("insert into book(bookname ,price ,publish) values(?,?,?)", "添加數據", [$("#bookname").val(), $("#price").val(), $("#publish").val()], function(result) { appDb.show(); }); }, //顯示數據 show: function() { appDb.exeSql("select id,bookname,price,publish from book", "顯示", [], function(result) { $("#tab_book 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)["bookname"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["price"]).appendTo(tr); $("<td/>").text(result.rows.item(i)["publish"]).appendTo(tr); var del = $("<a href='#' onclick='appDb.del(" + result.rows.item(i)['id'] + ",this)'>刪除</a>"); var audit = $("<a href='#' onclick='appDb.edit(" + result.rows.item(i)['id'] + ",this)'>編輯</a>"); $("<td/>").append(del).appendTo(tr); $("<td/>").append(audit).appendTo(tr); tr.appendTo("#tab_book"); } }); }, //刪除數據 del: function(id, link) { appDb.exeSql("delete from book where id=?", "刪除數據", [id], function(result) { $(link).closest("tr").remove(); }); }, //編輯數據 edit: function(id) { appDb.exeSql("select id,bookname,price,publish from book where id=?", "編輯數據", [id], function(result) { $("#bookname").val(result.rows.item(0)["bookname"]); $("#price").val(result.rows.item(0)["price"]); $("#publish").val(result.rows.item(0)["publish"]); $("#hidid").val(result.rows.item(0)["id"]); }); }, //修改數據 update: function() { if($("#hidid").val()) { appDb.exeSql("update book set bookname=?,price=? ,publish=? where id=?", "修改", [$("#bookname").val(), $("#price").val(), $("#publish").val(), $("#hidid").val()], function() { appDb.show(); $("#hidid").val(""); }); } else { appDb.log("請先選擇要操做的記錄!") } }, //顯示信息 log: function(msg) { $("#msg")[0].innerHTML += msg + "<br/>"; } } appDb.init();
</script> </body> </html>
5、移動端打包與運行
將手機與電腦鏈接到同一個網段,好比可使用wifi
查看本機ip地址,有時須要將本地鏈接禁用,查看ip地址的指令是ipconfig
在手機端使用瀏覽器查看結果以下:
這裏使用HBuilder打包成apk的安裝包,安裝打包結果以下:
這裏使用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> * { font-family: "microsoft yahei"; } .cart { width: 30px; height: 25px; text-align: right; cursor: pointer; } button { border-radius: 5px; height: 30px; width: 50px; padding: 5px; background-color: #6495ED; color: white; cursor: pointer; } button:hover { background-color: darkorange; } .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; } html,body{height:100%;} .wrap{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox; display:flex;-webkit-box-orient:vertical;-webkit-flex-direction:column; -ms-flex-direction:column;flex-direction:column;width:100%;height:100%;} .header,.footer{height:40px;line-height:40px;background-color:#D8D8D8;text-align:center;} .main{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;width:100%;} </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"> <ul class="mui-table-view mui-table-view-chevron"> <li id="switch" class="mui-table-view-cell"> 定時輪播 <div class="mui-switch"> <div class="mui-switch-handle"></div> </div> </li> </ul> <div id="slider" class="mui-slider"> <div class="mui-slider-group mui-slider-loop"> 額外增長的一個節點(循環輪播:第一個節點是最後一張輪播) <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 > <!--<button value="" id="btnCreateTable">建立表</button> <button value="" id="btnDropTable">刪除表</button>--> <button value="" id="btnRefresh">刷新</button> </div> <div class="title">個人購物車</div> <ul id="books_List_cart" class="mui-table-view mui-table-view-chevron"> </ul> <div class="title"> 圖書列表 </div> <ul id="books_List" class="mui-table-view mui-table-view-chevron"> </ul> </div> </div> <div id="tabbar-with-chat" class="mui-control-content"> <div class="title">添加圖書</div> <p><label for="bookname">書名:</label><input type="text" name="bookname" id="bookname" value="" /></p> <p><label for="price">價格:</label><input type="text" name="price" id="price" value="" /></p> <p><label for="publish">出版社:</label> <input type="text" name="publish" id="publish" list="dl1" value="" /> <datalist id="dl1"> <option>北京出版社</option> <option>玉林出版社</option> <option>清華出版社</option> <option>復旦出版社</option> <option>河北出版社</option> </datalist> <p><input type="button" name="btnAdd" id="btnAdd" value="添加" /></p> </div> <div id="tabbar-with-contact" class="mui-control-content"> <div class="wrap"> <div class="header">圖書管理</div> <div class="main"> <ul id="books_List2" class="mui-table-view mui-table-view-striped mui-table-view-condensed"> </ul> <input type="hidden" name="hidid" id="hidid" value="" /> <p><label for="ubookname">書名:</label><input type="text" name="ubookname" id="ubookname" value="" /></p> <p><label for="uprice">價格:</label><input type="text" name="uprice" id="uprice" value="" /></p> <p> <label for="upublish">出版社:</label> <input type="text" name="upublish" id="upublish" list="dl1" value="" /> <input type="button" name="btnUpdate" id="btnUpdate" value="修改" /> </p> </div> <div class="footer"></div> </div> </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> </ul> </div> </div> </body> <script src="js/jquery-1.10.2.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/mui.min.js"></script> <script> //[封裝二:]封裝js var appDb = { //打開數據庫 opendb: function() { this.db = openDatabase("Books", 1.0, "圖書", 1024 * 1024 * 3, function() { if(db) appDb.log("建立數據庫成功!"); }); }, //初始化 init: function() { this.opendb(); this.createTable(); this.show("#books_List"); this.show("#books_List2"); this.bindEvent(); appDb.log("初始化成功!"); }, //綁定事件 bindEvent: function() { //$("#btnCreateTable").click(appDb.createTable); //$("#btnDropTable").click(appDb.dropTable); $("#btnAdd").click(appDb.insert); $("#btnUpdate").click(appDb.update); $("#btnDelete").click(appDb.del); $("#btnRefresh").click(appDb.Refresh) }, Refresh:function(){ appDb.show("#books_List2"); appDb.show("#books_List"); }, //通用sql exeSql: function(sql, title, param, callback) { title || 操做; //若是title爲空,則取後面的'操做' appDb.db.transaction(function(tx) { tx.executeSql(sql, param || [], function(tx, result) { appDb.log(title + "成功!"); if(callback) callback(result); }, function(tx, error) { appDb.log(title + "失敗!" + error.Message) }); }); }, //建立表 createTable: function() { appDb.exeSql("create table if not exists book(id integer primary key autoincrement,bookname text,price double,publish text,imgSrc text)", "建立表"); }, //刪除表 dropTable: function() { appDb.exeSql("drop table book", "刪除表"); }, //添加數據 insert: function() { var id = parseInt(Math.random(8)*10); appDb.exeSql("insert into book(bookname ,price ,publish,imgSrc) values(?,?,?,?)", "添加數據", [$("#bookname").val(), $("#price").val(), $("#publish").val(), "images\/"+id+".png"], function(result) { appDb.show("#books_List2"); appDb.show("#books_List"); }); }, //顯示數據 :bl爲參數 show: function(bl) { if(bl == null) { bl = "#books_List"; } appDb.exeSql("select id,bookname,price,publish,imgSrc from book", "顯示", [], function(result) { $(bl + " li").remove(); for(var i = 0; i < result.rows.length; i++) { var li = $("<li class='mui-table-view-cell mui-media'/>"); var a = $("<a class='mui-navigate-right'/>"); var img = $("<img class='mui-media-object mui-pull-left' src='" + result.rows.item(i)['imgSrc'] + "'/>"); var div = $("<div class='mui-media-body'/>"); var p = $("<p class='mui-ellipsis'/>"); a.appendTo(li); img.appendTo(a); div.append(result.rows.item(i)["bookname"]).appendTo(a); p.text("價格僅售:" + result.rows.item(i)["price"] + "¥").appendTo(div); if(bl == "#books_List") { $("<p style='line-height: 30px;padding: 10px;'><img src='images/cart.png' class='cart'/><a onclick='appDb.Addcart(" + result.rows.item(i)['id'] + ")' href='#' >加入購物車</a><p/>").appendTo(p); } else { var del = $("<button onclick='appDb.del(" + result.rows.item(i)['id'] + ",this)'>刪除</button>"); var audit = $("<button onclick='appDb.edit(" + result.rows.item(i)['id'] + ",this)'>編輯</button>"); del.appendTo(div); audit.appendTo(div); } li.appendTo(bl); } }); }, //加入購物車 Addcart: function(id) { appDb.exeSql("select id,bookname,price,publish,imgSrc from book where id=?", "顯示", [id], function(result) { var li = $("<li class='mui-table-view-cell mui-media'/>"); var a = $("<a class='mui-navigate-right'/>"); var img = $("<img class='mui-media-object mui-pull-left' src='" + result.rows.item(0)['imgSrc'] + "'/>"); var div = $("<div class='mui-media-body'/>"); var p = $("<p class='mui-ellipsis'/>"); a.appendTo(li); img.appendTo(a); div.append(result.rows.item(0)["bookname"]).appendTo(a); p.text("價格" + result.rows.item(0)["price"] + "¥" + " 數量:1" ).appendTo(div); //p.append("<input type='checkbox'/>").appendTo(div); li.appendTo("#books_List_cart"); }); }, //刪除數據 del: function(id, link) { appDb.exeSql("delete from book where id=?", "刪除數據", [id], function(result) { $(link).closest("li").remove(); appDb.show("#books_List2"); appDb.show("#books_List"); }); }, //編輯數據 edit: function(id) { appDb.exeSql("select id,bookname,price,publish,imgSrc from book where id=?", "編輯數據", [id], function(result) { //把數據加載到文本框中 $("#ubookname").val(result.rows.item(0)["bookname"]); $("#uprice").val(result.rows.item(0)["price"]); $("#upublish").val(result.rows.item(0)["publish"]); $("#hidid").val(result.rows.item(0)["id"]); }); }, //修改數據 update: function() { if($("#hidid").val()) { appDb.exeSql("update book set bookname=?,price=? ,publish=? where id=?", "修改", [$("#ubookname").val(), $("#uprice").val(), $("#upublish").val(), $("#hidid").val()], function() { appDb.show("#books_List2"); $("#hidid").val(""); }); } else { appDb.log("請先選擇要操做的記錄!") } }, //顯示信息 log: function(msg) { mui.toast(msg); } } appDb.init(); //加載圖片 mui.init({ swipeBack: true //啓用右滑關閉功能 }); var slider = mui("#slider"); document.getElementById("switch").addEventListener('toggle', function(e) { if(e.detail.isActive) { slider.slider({ interval: 5000 }); } else { slider.slider({ interval: 0 }); } }); </script> </html>