一、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="data:images/yuantiao.jpg">
</a>
</div>
<!-- 第一张 -->
<div class="mui-slider-item">
<a href="#">
<img src="data:images/shuijiao.jpg">
</a>
</div>
<!-- 第二张 -->
<div class="mui-slider-item">
<a href="#">
<img src="data:images/muwu.jpg">
</a>
</div>
<!-- 第三张 -->
<div class="mui-slider-item">
<a href="#">
<img src="data:images/cbd.jpg">
</a>
</div>
<!-- 第四张 -->
<div class="mui-slider-item">
<a href="#">
<img src="data:images/yuantiao.jpg">
</a>
</div>
<!-- 额外增加的一个节点(循环轮播:最后一个节点是第一张轮播) -->
<div class="mui-slider-item mui-slider-item-duplicate">
<a href="#">
<img src="data: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="data: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="data: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="data: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="data: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="data: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>

打包运行后的结果如下:

六、示例下载

github:https://github.com/zhangguo5/HTML5_2_1

打包下载

参照:http://www.cnblogs.com/best

HTML5 学习笔记(三)——本地存储的更多相关文章

  1. HTML5学习笔记之客户端存储数据方法:localStorage(),sessionStorage()

    HTML5提供了两种在客户端存储数据的新方法: localStorage():没有时间限制的数据存储 sessionStorage():针对一个session的数据存储 下面的一个例子用localSt ...

  2. HTML5学习笔记<三>: HTML5样式, 连接和表格

    HTML样式 1, 标签: <style>: 样式定义 <link>: 资源引用 2. 属性: rel="stylesheet": 外部样式表 type=& ...

  3. HTML5学习笔记三 HTML元素、属性、标题、段落简介

    一.HTML 元素 HTML 元素以开始标签起始 HTML 元素以结束标签终止 元素的内容是开始标签与结束标签之间的内容 某些 HTML 元素具有空内容(empty content) 空元素在开始标签 ...

  4. HTML5学习笔记三:aside元素,time元素与微格式

    一.aside元素 表示当前页面或文章的附属信息部分,相关的引用,侧边栏,广告等有别于主要内容的部分:主要有一下两种用法: 1. 被包含在article元素中作为主要内容的附属信息部分,可以是与当前文 ...

  5. HTML5 学习笔记(一)——HTML5概要与新增标签

    目录 一.HTML5概要 1.1.为什么需要HTML5 1.2.什么是HTML5 1.3.HTML5现状及浏览器支持 1.4.HTML5特性 1.5.HTML5优点与缺点 1.5.1.优点 1.5.2 ...

  6. HTML5 学习笔记--------》HTML5概要与新增标签!

      一.HTML5概要 1.1.为什么需要HTML5 HTML4陈旧不能满足日益发展的互联网需要,特别是移动互联网.为了增强浏览器功能Flash被广泛使用,但安全与稳定堪忧,不适合在移动端使用(耗电. ...

  7. 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记

    回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...

  8. angular学习笔记(三十一)-$location(2)

    之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...

  9. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  10. html5学习笔记一

    HTML5学习笔记 <video>标记:定义视频,Ogg.MPEG4.WebM三种格式 <video src=”movie.ogg”  controls=”controls”> ...

随机推荐

  1. 静态界面传值javascript

    一:JavaScript静态页面值传递之URL篇能过URL进行传值.把要传递的信息接在URL上.Post.htm 复制代码代码如下: <input type="text" n ...

  2. android中xml tools属性详解

    第一部分 安卓开发中,在写布局代码的时候,ide可以看到布局的预览效果. 但是有些效果则必须在运行之后才能看见,比如这种情况:TextView在xml中没有设置任何字符,而是在activity中设置了 ...

  3. crontab详解

    搜索 纠正错误  添加实例 crontab 提交和管理用户的需要周期性执行的任务 补充说明 crontab命令 被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成 ...

  4. Filter实现用户名验证

    ①:使用Filter,判断用户名是否为空,为空的话返回登录画面. 1,web.xml: 1.<filter> 2. <filter-name>SecurityServlet&l ...

  5. Delphi Code Editor 之 编辑器选项

    Delphi Code Editor 之 编辑器选项 可从Code Editor的右键菜单中选择“Properties”菜单项来查看编辑器选项.也可以从主菜单[Tools | Editor Optio ...

  6. nodejs 编写(添加时间戳)命令行工具 timestamp

    Nodejs除了编写服务器端程序还可以编写命令行工具,如gulp.js就是Nodejs编写的. 接下来我们来实现一个添加时间戳的命令: $ timestamp action https://www.n ...

  7. linux下php-mysql拓展安装

    今天遇到一个奇怪的问题: 在服务器A上部署应用,在服务器B上部署数据库和缓存. 服务器A:apache2.2,php5.3 服务器B:mysql5.5,redis2.4 问题现象: 本地远程连接服务器 ...

  8. Web项目使用Oracle.DataAccess.dll 类库连接oracle数据库

    首先我用的工具是oracle 32位免安装版+Oracle.DataAccess.dll 32位  文件版本4.121.1.0+vs2013 +win7 64位 Oracle.DataAccess.d ...

  9. NFC OMA 访问

    正常的OMA访问: 但基本上IC原厂都会提供NFC swp-sim这一块的访问,但关于NFC内部eSe的访问一般NFC服务商又会整一套出来,导致有两套独立的SmartcardSevice需要运行,但他 ...

  10. Python实现简单的Web完整版(一)

    在拖了一周之后,今天终于在一个小时之内将一个迷你的Web写出来了,最近改其它项目的bug头好大,但是好喜欢这样的状态. 黑色的12月,所有的任务都聚集在了12月,然后期末考试也顾不上好好复习了,但是但 ...