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>