HTML5問世之後,前端加入了一個重要的功能,即是本地存儲,本地存儲可分爲4類:javascript
Local Storage:總的存儲量有所限制,並不能提供真正的檢索API,數據的生命期比窗口或瀏覽器的生命期長,數據可被同源的每一個窗口或者標籤頁共享,兼容性很好,使用最多的存儲方式。css
Session Storage:只要瀏覽器窗口不關閉就會一直存在,不該該把真正有價值的東西放在裏面,數據會保存到存儲它的窗口或者標籤頁關閉時,數據只在構建他們的窗口或者標籤頁可見html
Indexed Database:在Indexed Database中,objectstore代替了傳統的表的概念,每一個objectstore至關於一個key和value的集合,IndexedDB並不像傳統的如SQL Server那樣須要額外安裝。Indexed是存在於瀏覽器端的而且能被用戶所訪問控制。是保存不敏感用戶數據的最佳方案,也能夠用於建立本地應用,NOSql。前端
Web SQL Database:實際上未包含在HTML5規範中。和Indexed Database都是在客戶端存儲大量結構化數據的解決方案。web sql database實現了傳統的基於sql語句的數據庫操做,而indexed database實現了nosql的存儲方式,關係數據庫。java
Indexed Database經過直接執行同步或者異步的函數調用來檢索樹狀的對象存儲引擎。索引數據庫API避開了查詢字符串,它使用的底層API支持將值直接存儲在javascript對象中。存儲在數據庫中的值能夠經過鍵或使用索引獲取到,而且可使用同步或異步方式訪問API。索引數據庫也限定在同源範圍內。jquery
B/S架構的應用大量的信息存儲在服務器端,客戶端經過請求響應的方式從服務器得到數據,這樣集中存儲也會給服務器帶來相應的壓力,有些數據能夠直接存儲在客戶端,傳統的Web技術中會使用Cookie,但Cookie有一些缺點,爲了說明這個缺點咱們先看看當提交表單時會有那些信息會被瀏覽器收集後發送到服務器。android
Cookies 客戶端 獨享 4Kgit
Session 服務端 獨享 少許github
Application 服務端 共享 小量web
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等,結果以下:
顧名思義客戶端本地存儲就是將信息存儲在客戶端電腦上,cookie就是一種典型的傳統客戶端存儲,長期以來本地存儲能力一直是桌面應用區別於Web應用的一個主要優點,做爲Web應用程序而言,新一代的HTML標準對數據的本地存儲提出了更高的要求。傳統的Web數據存儲方式一直來使用的是Cookie,但Cookie有如下缺陷:
a)、cookie會被附加在每一個HTTP請求中,因此無形中增長了流量。
b)、因爲在HTTP請求中的cookie是明文傳遞的,因此安全性成問題。
c)、Cookie的大小限制在4 KB左右,容量達不到要求。
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 的存儲方式。
Web Storage 這種用於存儲 (key, value),通常二者都是字符串;
IndexDB 是加強型的 Web Storage,也是存儲 (key, value);
Web SQL 則是 SQLite,一個完整的關係型數據庫,能夠執行 SQL。
WebSQL是SQLite在瀏覽器中的實現,因此它是一種關係型數據庫。因爲W3C對其規範定義不夠理想,各家瀏覽器有各自實現,有瀏覽器兼容問題;
IndexDB是一種key-value類型的非關係數據庫(NoSQL)
https://github.com/js-cookie/js-cookie
官方幫助說明:
A simple, lightweight JavaScript API for handling cookies Works in all browsers Accepts any character Heavily tested No dependency Unobtrusive JSON support Supports AMD/CommonJS RFC 6265 compliant Useful Wiki Enable custom encoding/decoding ~900 bytes gzipped! If you're viewing this at https://github.com/js-cookie/js-cookie, you're reading the documentation for the master branch. View documentation for the latest release. Build Status Matrix (including active Pull Requests) Selenium Test Status Installation Direct download Download the script here and include it (unless you are packaging scripts somehow else): <script src="/path/to/js.cookie.js"></script> Or include it via jsDelivr CDN: <script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script> Do not include the script directly from GitHub (http://raw.github.com/...). The file is being served as text/plain and as such being blocked in Internet Explorer on Windows 7 for instance (because of the wrong MIME type). Bottom line: GitHub is not a CDN. Package Managers JavaScript Cookie supports npm and Bower under the name js-cookie. NPM $ npm install js-cookie --save Module Loaders JavaScript Cookie can also be loaded as an AMD or CommonJS module. Basic Usage Create a cookie, valid across the entire site: Cookies.set('name', 'value'); Create a cookie that expires 7 days from now, valid across the entire site: Cookies.set('name', 'value', { expires: 7 }); Create an expiring cookie, valid to the path of the current page: Cookies.set('name', 'value', { expires: 7, path: '' }); Read cookie: Cookies.get('name'); // => 'value' Cookies.get('nothing'); // => undefined Read all visible cookies: Cookies.get(); // => { name: 'value' } Note: It is not possible to read a particular cookie by passing one of the cookie attributes (which may or may not have been used when writing the cookie in question): Cookies.get('foo', { domain: 'sub.example.com' }); // `domain` won't have any effect...! The cookie with the name foo will only be available on .get() if it's visible from where the code is called; the domain and/or path attribute will not have an effect when reading. Delete cookie: Cookies.remove('name'); Delete a cookie valid to the path of the current page: Cookies.set('name', 'value', { path: '' }); Cookies.remove('name'); // fail! Cookies.remove('name', { path: '' }); // removed! IMPORTANT! When deleting a cookie, you must pass the exact same path and domain attributes that were used to set the cookie, unless you're relying on the default attributes. Note: Removing a nonexistent cookie does not raise any exception nor return any value. Namespace conflicts If there is any danger of a conflict with the namespace Cookies, the noConflict method will allow you to define a new namespace and preserve the original one. This is especially useful when running the script on third party sites e.g. as part of a widget or SDK. // Assign the js-cookie api to a different variable and restore the original "window.Cookies" var Cookies2 = Cookies.noConflict(); Cookies2.set('name', 'value'); Note: The .noConflict method is not necessary when using AMD or CommonJS, thus it is not exposed in those environments. JSON js-cookie provides unobtrusive JSON storage for cookies. When creating a cookie you can pass an Array or Object Literal instead of a string in the value. If you do so, js-cookie will store the string representation of the object according to JSON.stringify: Cookies.set('name', { foo: 'bar' }); When reading a cookie with the default Cookies.get api, you receive the string representation stored in the cookie: Cookies.get('name'); // => '{"foo":"bar"}' Cookies.get(); // => { name: '{"foo":"bar"}' } When reading a cookie with the Cookies.getJSON api, you receive the parsed representation of the string stored in the cookie according to JSON.parse: Cookies.getJSON('name'); // => { foo: 'bar' } Cookies.getJSON(); // => { name: { foo: 'bar' } } Note: To support IE6-7 (and IE 8 compatibility mode) you need to include the JSON-js polyfill: https://github.com/douglascrockford/JSON-js Encoding This project is RFC 6265 compliant. All special characters that are not allowed in the cookie-name or cookie-value are encoded with each one's UTF-8 Hex equivalent using percent-encoding. The only character in cookie-name or cookie-value that is allowed and still encoded is the percent % character, it is escaped in order to interpret percent input as literal. Please note that the default encoding/decoding strategy is meant to be interoperable only between cookies that are read/written by js-cookie. To override the default encoding/decoding strategy you need to use a converter. Cookie Attributes Cookie attributes defaults can be set globally by setting properties of the Cookies.defaults object or individually for each call to Cookies.set(...) by passing a plain object in the last argument. Per-call attributes override the default attributes. expires Define when the cookie will be removed. Value can be a Number which will be interpreted as days from time of creation or a Date instance. If omitted, the cookie becomes a session cookie. To create a cookie that expires in less than a day, you can check the FAQ on the Wiki. Default: Cookie is removed when the user closes the browser. Examples: Cookies.set('name', 'value', { expires: 365 }); Cookies.get('name'); // => 'value' Cookies.remove('name'); path A String indicating the path where the cookie is visible. Default: / Examples: Cookies.set('name', 'value', { path: '' }); Cookies.get('name'); // => 'value' Cookies.remove('name', { path: '' }); Note regarding Internet Explorer: Due to an obscure bug in the underlying WinINET InternetGetCookie implementation, IE’s document.cookie will not return a cookie if it was set with a path attribute containing a filename. (From Internet Explorer Cookie Internals (FAQ)) This means one cannot set a path using window.location.pathname in case such pathname contains a filename like so: /check.html (or at least, such cookie cannot be read correctly). In fact, you should never allow untrusted input to set the cookie attributes or you might be exposed to a XSS attack. domain A String indicating a valid domain where the cookie should be visible. The cookie will also be visible to all subdomains. Default: Cookie is visible only to the domain or subdomain of the page where the cookie was created, except for Internet Explorer (see below). Examples: Assuming a cookie that is being created on site.com: Cookies.set('name', 'value', { domain: 'subdomain.site.com' }); Cookies.get('name'); // => undefined (need to read at 'subdomain.site.com') Note regarding Internet Explorer default behavior: Q3: If I don’t specify a DOMAIN attribute (for) a cookie, IE sends it to all nested subdomains anyway? A: Yes, a cookie set on example.com will be sent to sub2.sub1.example.com. Internet Explorer differs from other browsers in this regard. (From Internet Explorer Cookie Internals (FAQ)) This means that if you omit the domain attribute, it will be visible for a subdomain in IE. secure Either true or false, indicating if the cookie transmission requires a secure protocol (https). Default: No secure protocol requirement. Examples: Cookies.set('name', 'value', { secure: true }); Cookies.get('name'); // => 'value' Cookies.remove('name'); Converters Read Create a new instance of the api that overrides the default decoding implementation. All get methods that rely in a proper decoding to work, such as Cookies.get() and Cookies.get('name'), will run the converter first for each cookie. The returning String will be used as the cookie value. Example from reading one of the cookies that can only be decoded using the escape function: document.cookie = 'escaped=%u5317'; document.cookie = 'default=%E5%8C%97'; var cookies = Cookies.withConverter(function (value, name) { if ( name === 'escaped' ) { return unescape(value); } }); cookies.get('escaped'); // 北 cookies.get('default'); // 北 cookies.get(); // { escaped: '北', default: '北' } Write Create a new instance of the api that overrides the default encoding implementation: Cookies.withConverter({ read: function (value, name) { // Read converter }, write: function (value, name) { // Write converter } }); Server-side integration Check out the Servers Docs Contributing Check out the Contributing Guidelines Security For vulnerability reports, send an e-mail to jscookieproject at gmail dot com Manual release steps Increment the "version" attribute of package.json Increment the version number in the src/js.cookie.js file If major bump, update jsDelivr CDN major version link on README Commit with the message "Release version x.x.x" Create version tag in git Create a github release and upload the minified file Change the latest tag pointer to the latest commit git tag -f latest git push <remote> :refs/tags/latest git push origin master --tags Release on npm Authors Klaus Hartl Fagner Brack And awesome contributors
一、寫
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>客戶端讀寫Cookie</title> </head> <body> <button type="button" onclick="writeCookie();">寫</button> <button type="button" onclick="readCookie();">讀</button> <button type="button" onclick="removeCookie();">清除</button> <script src="js.cookie-2.2.0.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> function writeCookie(){ //在當前域下寫入cookie Cookies.set('price', '998', { expires: 7 }); } </script> </body> </html>
運行結果:
二、讀
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>客戶端讀寫Cookie</title> </head> <body> <button type="button" onclick="writeCookie();">寫</button> <button type="button" onclick="readCookie();">讀</button> <button type="button" onclick="removeCookie();">清除</button> <script src="js.cookie-2.2.0.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> function writeCookie(){ //在當前域下寫入cookie Cookies.set('price', '998', { expires: 7 }); } function readCookie(){ //在當前域根據key讀取cookie var price=Cookies.get("price"); alert("價格:"+price); } </script> </body> </html>
結果:
三、清除
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>客戶端讀寫Cookie</title> </head> <body> <button type="button" onclick="writeCookie();">寫</button> <button type="button" onclick="readCookie();">讀</button> <button type="button" onclick="removeCookie();">清除</button> <script src="js.cookie-2.2.0.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> function writeCookie(){ //在當前域下寫入cookie Cookies.set('price', '998', { expires: 7 }); //過時時間爲7天 Cookies.set('color', 'blue', { expires: 7 }); } function readCookie(){ //在當前域根據key讀取cookie var price=Cookies.get("price"); alert("價格:"+price); } function removeCookie(){ //在當前域指定的cookie Cookies.remove("price"); } console.log(document.cookie); </script> </body> </html>
結果:
localStorage:將數據保存在客戶端本地的硬件設備(一般指硬盤,但也能夠是其餘硬件設備)中,即便瀏覽器被關閉了,該數據仍然存在,下次打開瀏覽器訪問網站時仍然能夠繼續使用。
<!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>
運行結果:
<!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>
運行結果:
//修改 function update_click() { //若是不存在就添加,若是存在就修改 localStorage.setItem("name","iPhone 8 plus手機"); //修改辦法2 localStorage["price"]=899.5; //修改辦法3 localStorage.amount=100; }
運行結果:
<!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>
運行結果:
當關閉瀏覽器,下次再打開時,值仍然存在。能夠跨頁面,不能跨域。咱們在d01頁面中添加了值,在d02頁面中仍然能夠訪問,在整個同域下均可以訪問。
localStorage與cookie不同,它存儲在一個數據庫文件中,默認位置在:C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\databases\http_localhost_*
或者
C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Profile 1\Local Storage
Administrator是當前登陸用戶名
使用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)等
登陸成功後記錄用戶訪問次數。
在IE8中測試經過
Firefox測試經過
將數據臨時保存在客戶端session對象中。session對象就是會話對象,session中存儲的數據獨立於每一個客戶,該數據會隨着瀏覽器的關閉而消失。
sessionStorage的操做api與localStorage基本同樣,在不手動清除的狀況下localStorage永久保存,而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>
運行結果:
能夠實如今頁面間傳值,好比能夠臨時存儲用戶信息。
當程序修改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).回調函數(可省略)
<!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>
運行結果:
執行全部的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爲自動增加用的序列。
頁面腳本以下:
<!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>
運行結果:
頁面腳本以下:
<!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>
運行結果以下:
頁面腳本以下:
<!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>
運行結果以下:
<!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>
運行結果:
刪除表
//建立表 function dropTable() { db.transaction(function(tx) { tx.executeSql( "drop table IF EXISTS goods", [], function(tx, result) { log('刪除表成功'); }, function(tx, error) { log('刪除表失敗' + error.message); }); }); }
運行結果:
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
回調方法:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script type="text/javascript"> var ticker={ n:0, add:function(){ this.n++; }, show:function(){ alert(ticker.n); } }; ticker.add(); ticker.add(); ticker.show(); function add(a,b){ var sum=a+b; alert(a+"+"+b+"="+sum); } calc(1,2,add); calc(5,8,function(c,d){ alert(c+"-"+d+"="+(c-d)); }); function calc(n1,n2,fun){ if(n1>0&&n2>0&&fun){ fun(n1,n2); }else{ alert("參數缺失"); } } </script> </body> </html>
封裝結果:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>WebSqlDataBase</title> </head> <body> <h2>WebSqlDataBase</h2> <button onclick="app.openDb()">建立/打開數據庫</button> <button onclick="app.createTable()">建立數據表</button> <button onclick="app.insert()">添加數據</button> <button onclick="app.update()">修改數據</button> <button onclick="app.remove()">刪除數據</button> <button onclick="app.select()">查詢數據</button> <button onclick="app.dropTable()">刪除表</button> <p> 編號:<input type="text" id="id" /> </p> <p> 名稱:<input type="text" id="name" /> </p> <p> <h2 id="h2Msg"></h2> </p> <script type="text/javascript"> var app = { db: {}, data: { id: document.querySelector("#id").value, name: document.querySelector("#name").value }, init: function() { window.log = function(msg) { console.log(msg); document.getElementById("h2Msg").innerHTML += msg + "<br/>"; } app.openDb(); }, openDb: function() { //建立或打開數據庫 app.db = openDatabase("gomallDb", "1.0", "天狗商城", 1024 * 1024 * 3, function() { log("建立或打開數據庫成功"); }); }, executeSql: function(sql, params, success, error) { if(app.db) { app.db.transaction(function(tx) { tx.executeSql(sql, params || [], function(tx, result) { log("執行成功!"); if(success) { success(tx, result); } }, function(tx, result) { log("執行失敗!"); if(error) { error(tx, result); } }); }); } else { log("請打開數據庫"); } }, createTable: function() { //建立表 var sql = "create table if not exists goods(id integer primary key autoincrement,name text not null);"; app.executeSql(sql); }, insert: function() { //添加數據 app.executeSql("insert into goods(name) values(?)", [app.data.name]); }, update: function() { //修改數據 app.executeSql("update goods set name=? where id=?", [app.data.name, app.data.id]); }, remove: function() { //刪除數據 app.executeSql("delete from goods where name like ? or id=?", [app.data.name, app.data.id]); }, select: function() { //查詢 app.executeSql("select id,name from goods", [], function(tx, result) { var r = result.rows; for(var i = 0; i < r.length; i++) { log(r[i].id + "," + r[i].name); } }); }, dropTable: function() { //刪除表 app.executeSql("drop table if exists goods", [], function() { alert("刪除成功!") }, function() { alert("刪除失敗!"); } ) } }; app.init(); </script> </body> </html>
第一次封裝後的代碼,在整個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>
運行結果:
在原頁面的基礎上增長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>
運行結果:
IndexedDB是在瀏覽器中保存結構化數據的一種數據庫,爲了替換WebSQL(標準已廢棄,但被普遍支持)而出現。IndexedDB使用NoSQL的形式來操做數據庫,保存和讀取是JavaScript對象,同時還支持查詢及搜索。
API: https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API
示例代碼:
if('indexedDB' in window){ //檢測是否支持indexed database }else{ mui.alert('您的手機佔不支持'); } //數據庫信息 var DB = { name:'admin_users', version:1 } var db; function openDB(name,version){ //第一個參數是數據庫名稱,若是存在則打開,若是不存在就建立 //第二個參數是數據庫版本,用於更新數據庫結構 var request = window.indexedDB.open(name,version); request.onerror = function(e){ mui.alert('打開數據庫失敗'); } request.onsuccess = function(e){ db = request.result; ReadAll(); } //操做數據庫(建立刪除修改) //首次打開數據庫或改變數據庫版本的時候觸發 request.onupgradeneeded = function(e){ //使用createObjectStore()方法建立一個對象存儲 //此方法接受兩個參數:存儲的名稱和參數對象 //keypath是用戶數據的惟一標識 或者使用索引 var objectStore = e.target.result.createObjectStore("users",{keyPath:'name'}); } } function Add(name,account,password){ //transaction()方法是用來指定咱們想要進行事務處理的對象存儲,接受3個參數 //第一個(必選)要處理的對象存儲的列表數組 //第二個(可選)指定操做方式 只讀/讀寫 //第三個(可選)版本變化 //add()方法用於添加數據 var request = db.transaction(["users"],"readwrite").objectStore("users").add({ name:name, account:account, password:password }); request.onsuccess = function(e){ mui.toast('成功'); var list = document.querySelector('#list'); var dom = '<li class="mui-table-view-cell mui-collapse">'; dom+= '<a class="mui-navigate-right" href="#">'+name+'</a>'; dom+= '<div class="mui-collapse-content"><p><span>帳號:</span>'+account+'</p>'; dom+= '<p><span>密碼:</span>'+password+'</p></div></li>'; list.innerHTML += dom; } request.onerror = function(e){ mui.toast('失敗'); } } function Read(name){ var objectStore = db.transaction(["users"]).objectStore("users"); //get()方法用於獲取數據 var request = objectStore.get(name); request.onerror = function(event){ mui.toast('讀取失敗'); } request.onsuccess = function(event){ if(request.result){ console.log(request.result); } } } function ReadAll(){ var objectStore = db.transaction("users").objectStore("users"); //openCursor()方法用於獲取全部數據 var request = objectStore.openCursor(); request.onsuccess = function(event){ //db.close(); var res = event.target.result; var list = document.querySelector('#list'); if(res){ var dom = '<li class="mui-table-view-cell mui-collapse">'; dom+= '<a class="mui-navigate-right" href="#">'+res.value.name+'</a>'; dom+= '<div class="mui-collapse-content"><p><span>帳號:</span>'+res.value.account+'</p>'; dom+= '<p><span>密碼:</span>'+res.value.password+'</p></div></li>'; list.innerHTML += dom; //console.log(res.value); res.continue(); } } request.onerror = function(e){ mui.toast('讀取失敗') } } function Remove(name){ //delete()方法用於刪除數據 var request = db.transaction("users","readwrite").objectStore('users').delete(name); request.onsuccess = function(event){ mui.toast('刪除成功'); } request.onerror = function(){ mui.toast('刪除失敗') } } openDB(DB.name,DB.version); var submits = document.querySelector('#submit'); function display(dis){ var bg = document.querySelectorAll('.alert-bg')[0]; var alert = document.querySelectorAll('.alert')[0]; alert.style.display = dis; bg.style.display = dis; } submits.onclick = function(){ var name = document.querySelector('#name').value; var account = document.querySelector('#account').value; var password = document.querySelector('#password').value; if(!name || !account || !password){ return mui.toast('請輸入完整信息'); } display('none'); Add(name,account,password) }
IndexedDB保存的是對象,而不是使用表保存數據。打開數據庫使用indexDB.open方法,這方法有兩個參數,第一個是數據庫名稱,第二個是數據版本號。
IndexedDB的操做徹底是異步進行的,每一次IndexedDB操做,都須要註冊onerror或onsuccess事件處理程序。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDB</title> </head> <body> <h2>IndexedDB(NOSQL)</h2> <input value="建立數據庫與表" type="button" onclick="create()" /> <h2 id="msg"></h2> <script> //數據庫 var db; //建立數據庫與表 function create() { //建立一個名稱爲gomall且版本爲2的數據庫,返回一個請求 var request = indexedDB.open("gomall", 2); //綁定回調事件,成功時 request.onsuccess = function(e) { db = e.target.result; log('建立數據庫成功'); }; //失敗時 request.onerror = function(e) { log("錯誤:" + e.target.errorCode || e.target.error); }; //增長數據庫版本號時,會觸發onupgradeneeded事件(會在onsuccess以前被調用) request.onupgradeneeded = function(e) { //建立對象存儲空間(ObjectStore),相似表,goods是表名,id是主鍵,存儲的是JSON e.target.result.createObjectStore("goods",{"keyPath":"id"}); log("初始化數據庫成功!"); }; } //顯示消息 var msg = document.getElementById("msg"); function log(m) { msg.innerHTML += m + "<br/>"; } //用於判斷瀏覽器是否支持indexedDB,0,null,'',undefind false if(window.indexedDB) { } else { alert('請升級瀏覽器,如chrome'); } </script> </body> </html>
這裏要注意的是,數據庫版本只會有最新一個,不會同時存在兩個版本的同名數據庫。
運行結果:
對象存儲空間(ObjectStore)能夠想象成關係數據庫的表,在初始化DB觸發onupgradeneeded時,建立ObjectStore。使用createObjectStore方法,第一個參數是對象名,第二個參數是對象屬性,通常是設置keyPath(做爲鍵使用)。
由於對新數據的操做都須要在transaction中進行,而transaction又要求指定object store,因此咱們只能在建立數據庫的時候初始化object store以供後面使用,這正是onupgradeneeded的一個重要做用
有了數據庫後咱們天然但願建立一個表用來存儲數據,但indexedDB中沒有表的概念,而是objectStore,一個數據庫中能夠包含多個objectStore,objectStore是一個靈活的數據結構,能夠存放多種類型數據。也就是說一個objectStore至關於一張表,裏面存儲的每條數據和一個鍵相關聯。
咱們可使用每條記錄中的某個指定字段做爲鍵值(keyPath),也可使用自動生成的遞增數字做爲鍵值(keyGenerator),也能夠不指定。選擇鍵的類型不一樣,objectStore能夠存儲的數據結構也有差別
不使用—>任意值,可是沒添加一條數據的時候須要指定鍵參數
keyPath—>Javascript對象,對象必須有一屬性做爲鍵值
keyGenerator—>任意值(db.createObjectStore('students',{autoIncrement: true});)
都使用—>Javascript對象,若是對象中有keyPath指定的屬性則不生成新的鍵值,若是沒有自動生成遞增鍵值,填充keyPath指定屬性
req.onupgradeneeded = function (evt) { console.debug("initDb.onupgradeneeded"); var db = evt.currentTarget.result; //ObjectStore必須在onupgradeneeded裏建立,其餘地方將會建立失敗 var usersStore = db.createObjectStore("users", { keyPath : "id" }); };
效果以下:
全部讀取或修改數據的操做,都要經過事務來完成。建立事務使用transaction方法,第一個參數是須要訪問的ObjectStore,第二個參數是訪問模式(readwrite可讀可寫、readonly只讀,默認是隻讀)。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDB</title> </head> <body> <h2>IndexedDB(NOSQL)</h2> <input value="建立數據庫與表" type="button" onclick="create()" /> <input value="新增數據" type="button" onclick="add()" /> <h2 id="msg"></h2> <script> //數據庫 var db; //建立數據庫與表 function create() { //建立一個名稱爲gomall且版本爲2的數據庫,返回一個請求 var request = indexedDB.open("gomall", 2); //綁定回調事件,成功時 request.onsuccess = function(e) { db = e.target.result; log('建立數據庫成功'); }; //失敗時 request.onerror = function(e) { log("錯誤:" + e.target.errorCode || e.target.error); }; //增長數據庫版本號時,會觸發onupgradeneeded事件(會在onsuccess以前被調用) request.onupgradeneeded = function(e) { //建立對象存儲空間(ObjectStore),相似表,goods是表名,id是主鍵,存儲的是JSON e.target.result.createObjectStore("goods",{"keyPath":"id"}); log("初始化數據庫成功!"); }; } //新增數據 function add(){ //建立事務對象 var tx=db.transaction("goods","readwrite"); //從數據庫中得到存儲對象,表 var goods=tx.objectStore("goods"); //javascript中的對象數組 var items=[{"id":1,"name":"iPhone 11","price":19999.5},{"id":2,"name":"華爲榮耀V9","price":1997.3}]; for(var i=0;i<items.length;i++){ goods.add(items[i]); } log("添加數據成功!"); } //顯示消息 var msg = document.getElementById("msg"); function log(m) { msg.innerHTML += m + "<br/>"; } //用於判斷瀏覽器是否支持indexedDB,0,null,'',undefind false if(window.indexedDB) { } else { alert('請升級瀏覽器,如chrome'); } </script> </body> </html>
結果:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDB</title> </head> <body> <h2>IndexedDB(NOSQL)</h2> <input value="建立數據庫與表" type="button" onclick="create()" /> <input value="新增數據" type="button" onclick="add()" /> <input value="得到單個對象" type="button" onclick="getSingle()" /> <h2 id="msg"></h2> <script> //數據庫 var db; //建立數據庫與表 function create() { //建立一個名稱爲gomall且版本爲2的數據庫,返回一個請求 var request = indexedDB.open("gomall", 2); //綁定回調事件,成功時 request.onsuccess = function(e) { db = e.target.result; log('建立數據庫成功'); }; //失敗時 request.onerror = function(e) { log("錯誤:" + e.target.errorCode || e.target.error); }; //增長數據庫版本號時,會觸發onupgradeneeded事件(會在onsuccess以前被調用) request.onupgradeneeded = function(e) { //建立對象存儲空間(ObjectStore),相似表,goods是表名,id是主鍵,存儲的是JSON e.target.result.createObjectStore("goods", { "keyPath": "id" }); log("初始化數據庫成功!"); }; } //新增數據 function add() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var items = [{ "id": 1, "name": "iPhone 11", "price": 19999.5 }, { "id": 2, "name": "華爲榮耀V9", "price": 1997.3 }]; for(var i = 0; i < items.length; i++) { goods.add(items[i]); } log("添加數據成功!"); } //得到單個對象 function getSingle() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //請求key爲1的對象 var request=goods.get(1); request.onsuccess=function(e){ var obj=e.target.result; //JSON.stringify將obj對象轉換成字符 log(JSON.stringify(obj)); log(obj.id+","+obj.name+","+obj.price); }; } //顯示消息 var msg = document.getElementById("msg"); function log(m) { msg.innerHTML += m + "<br/>"; } //用於判斷瀏覽器是否支持indexedDB,0,null,'',undefind false if(window.indexedDB) { } else { alert('請升級瀏覽器,如chrome'); } </script> </body> </html>
結果:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDB</title> </head> <body> <h2>IndexedDB(NOSQL)</h2> <input value="建立數據庫與表" type="button" onclick="create()" /> <input value="新增數據" type="button" onclick="add()" /> <input value="得到單個對象" type="button" onclick="getSingle()" /> <input value="更新對象" type="button" onclick="edit()" /> <h2 id="msg"></h2> <script> //數據庫 var db; //建立數據庫與表 function create() { //建立一個名稱爲gomall且版本爲2的數據庫,返回一個請求 var request = indexedDB.open("gomall", 2); //綁定回調事件,成功時 request.onsuccess = function(e) { db = e.target.result; log('建立數據庫成功'); }; //失敗時 request.onerror = function(e) { log("錯誤:" + e.target.errorCode || e.target.error); }; //增長數據庫版本號時,會觸發onupgradeneeded事件(會在onsuccess以前被調用) request.onupgradeneeded = function(e) { //建立對象存儲空間(ObjectStore),相似表,goods是表名,id是主鍵,存儲的是JSON e.target.result.createObjectStore("goods", { "keyPath": "id" }); log("初始化數據庫成功!"); }; } //新增數據 function add() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var items = [{ "id": 1, "name": "iPhone 11", "price": 19999.5 }, { "id": 2, "name": "華爲榮耀V9", "price": 1997.3 }]; for(var i = 0; i < items.length; i++) { goods.add(items[i]); } log("添加數據成功!"); } //得到單個對象 function getSingle() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //請求key爲1的對象 var request = goods.get(2); request.onsuccess = function(e) { var obj = e.target.result; //JSON.stringify將obj對象轉換成字符 log(JSON.stringify(obj)); log(obj.id + "," + obj.name + "," + obj.price); }; } //更新對象 function edit() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var item = { "id": 2, "name": "華爲榮耀P15", "price":1357.9, "os":"android" }; //執行更新 var request=goods.put(item); request.onsuccess=function(e){ log(e.target.result); }; } //顯示消息 var msg = document.getElementById("msg"); function log(m) { msg.innerHTML += m + "<br/>"; } //用於判斷瀏覽器是否支持indexedDB,0,null,'',undefind false if(window.indexedDB) { } else { alert('請升級瀏覽器,如chrome'); } </script> </body> </html>
結果:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDB</title> </head> <body> <h2>IndexedDB(NOSQL)</h2> <input value="建立數據庫與表" type="button" onclick="create()" /> <input value="新增數據" type="button" onclick="add()" /> <input value="得到單個對象" type="button" onclick="getSingle()" /> <input value="更新對象" type="button" onclick="edit()" /> <input value="刪除對象" type="button" onclick="del()" /> <h2 id="msg"></h2> <script> //數據庫 var db; //建立數據庫與表 function create() { //建立一個名稱爲gomall且版本爲2的數據庫,返回一個請求 var request = indexedDB.open("gomall", 2); //綁定回調事件,成功時 request.onsuccess = function(e) { db = e.target.result; log('建立數據庫成功'); }; //失敗時 request.onerror = function(e) { log("錯誤:" + e.target.errorCode || e.target.error); }; //增長數據庫版本號時,會觸發onupgradeneeded事件(會在onsuccess以前被調用) request.onupgradeneeded = function(e) { //建立對象存儲空間(ObjectStore),相似表,goods是表名,id是主鍵,存儲的是JSON e.target.result.createObjectStore("goods", { "keyPath": "id" }); log("初始化數據庫成功!"); }; } //新增數據 function add() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var items = [{ "id": 1, "name": "iPhone 11", "price": 19999.5 }, { "id": 2, "name": "華爲榮耀V9", "price": 1997.3 }]; for(var i = 0; i < items.length; i++) { goods.add(items[i]); } log("添加數據成功!"); } //得到單個對象 function getSingle() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //請求key爲1的對象 var request = goods.get(2); request.onsuccess = function(e) { var obj = e.target.result; //JSON.stringify將obj對象轉換成字符 log(JSON.stringify(obj)); log(obj.id + "," + obj.name + "," + obj.price); }; } //更新對象 function edit() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var item = { "id": 2, "name": "華爲榮耀P15", "price":1357.9, "os":"android" }; //執行更新 var request=goods.put(item); request.onsuccess=function(e){ log(e.target.result); }; } //刪除對象 function del() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //執行刪除操做 var request=goods.delete(2); //成功時的回調 request.onsuccess=function(e){ log(e.target.result); }; } //顯示消息 var msg = document.getElementById("msg"); function log(m) { msg.innerHTML += m + "<br/>"; } //用於判斷瀏覽器是否支持indexedDB,0,null,'',undefind false if(window.indexedDB) { } else { alert('請升級瀏覽器,如chrome'); } </script> </body> </html>
結果:
function clearData(){ var tx = db.transaction("users", READ_WRITE); var store = tx.objectStore("users"); var req = store.clear(); req.onsuccess = function (evt) { console.debug("clearData success"); }; req.onerror = function (evt) { console.error("clearData error:", evt.target.errorCode || evt.target.error); }; }
使用事務能夠直接經過鍵檢索單個對象,而須要檢索多個對象時候就須要使用遊標。遊標是指向結果集的指針,不提早收集結果。遊標指針會先指向結果中的第一項,在接到查找下一項指令時,纔會指向下一項。
function openCursor(){ var tx = db.transaction("users", READ_WRITE); var store = tx.objectStore("users"); var req = store.openCursor(); req.onsuccess = function (evt) { var cursor = evt.target.result; if(cursor){ //必要檢查 var value = cursor.value; console.log(value); if(value.name == '楊冪'){ value.age = 16; cursor.update(value); //修改數據(必須是讀寫模式) } if(value.name == '柳巖'){ cursor.delete(); //刪除當前項 } cursor.continue(); //移動到下一項 } }; req.onerror = function (evt) { console.error("openCursor error:", evt.target.errorCode || evt.target.error); }; }
這裏有幾點要注意:
1. 若是須要修改或刪除數據,就須要打開成讀寫模式。
2. cursor的非空校驗是必要的。
3. 修改或刪除的操做也是有onsuccess和onerror的,只是在示例中沒有寫出來。
4. 調用continue纔會移動到下一項
另外能夠設置遊標的鍵範圍和遊標的方向,即打開openCursor方法時能夠傳這兩個參數(openCursor(鍵範圍,方向)),第一個參數是object類型,第二個參數是字符串類型。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDB</title> </head> <body> <h2>IndexedDB(NOSQL)</h2> <input value="建立數據庫與表" type="button" onclick="create()" /> <input value="新增數據" type="button" onclick="add()" /> <input value="得到單個對象" type="button" onclick="getSingle()" /> <input value="更新對象" type="button" onclick="edit()" /> <input value="刪除對象" type="button" onclick="del()" /> <input value="得到多個對象(遊標)" type="button" onclick="getAll()" /> <h2 id="msg"></h2> <script> //數據庫 var db; //建立數據庫與表 function create() { //建立一個名稱爲gomall且版本爲2的數據庫,返回一個請求 var request = indexedDB.open("gomall", 2); //綁定回調事件,成功時 request.onsuccess = function(e) { db = e.target.result; log('建立數據庫成功'); }; //失敗時 request.onerror = function(e) { log("錯誤:" + e.target.errorCode || e.target.error); }; //增長數據庫版本號時,會觸發onupgradeneeded事件(會在onsuccess以前被調用) request.onupgradeneeded = function(e) { //建立對象存儲空間(ObjectStore),相似表,goods是表名,id是主鍵,存儲的是JSON e.target.result.createObjectStore("goods", { "keyPath": "id" }); log("初始化數據庫成功!"); }; } //新增數據 function add() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var items = [{ "id": 2, "name": "iPhone 13", "price": 19999.5 }, { "id": 3, "name": "華爲榮耀V10", "price": 1997.3 }]; for(var i = 0; i < items.length; i++) { goods.add(items[i]); } log("添加數據成功!"); } //得到單個對象 function getSingle() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //請求key爲1的對象 var request = goods.get(2); request.onsuccess = function(e) { var obj = e.target.result; //JSON.stringify將obj對象轉換成字符 log(JSON.stringify(obj)); log(obj.id + "," + obj.name + "," + obj.price); }; } //更新對象 function edit() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var item = { "id": 2, "name": "華爲榮耀P15", "price": 1357.9, "os": "android" }; //執行更新 var request = goods.put(item); request.onsuccess = function(e) { log(e.target.result); }; } //刪除對象 function del() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //執行刪除操做 var request = goods.delete(2); //成功時的回調 request.onsuccess = function(e) { log(e.target.result); }; } //得到多個對象(遊標) function getAll() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //打開遊標 var request = goods.openCursor(); //成功時的回調 request.onsuccess = function(e) { //得到遊標 var cursor = e.target.result; if(cursor) { //若是不爲空 var obj = cursor.value; log(JSON.stringify(obj)); //下移 cursor.continue(); } }; } //顯示消息 var msg = document.getElementById("msg"); function log(m) { msg.innerHTML += m + "<br/>"; } //用於判斷瀏覽器是否支持indexedDB,0,null,'',undefind false if(window.indexedDB) { } else { alert('請升級瀏覽器,如chrome'); } </script> </body> </html>
結果:
鍵範圍由IDBKeyRange的實例表示。
IDBKeyRange.only('001'); //只想要鍵爲001的結果 IDBKeyRange.lowerBound('002'); //從鍵爲002開始,到最後 IDBKeyRange.lowerBound('002', true); //從鍵爲002開始,但忽略002,到最後 IDBKeyRange.upperBound('002'); //從頭開始,到鍵爲002爲止 IDBKeyRange.upperBound('002', true); //從頭開始,到鍵爲002爲止,但忽略002 IDBKeyRange.bound('001', '005'); //從001開始,到爲005爲止 IDBKeyRange.bound('001', '005', true, true); //從001開始,到爲005爲止,但忽略00一、005
next : 從第一項到最後一項(默認)
prev : 從最後一項到第一項
索引
當須要使用其餘屬性(非主鍵)獲取數據時,就要預先建立索引,而後使用索引獲取數據。
建立索引(在數據庫初始化onupgradeneeded事件時)
第一個參數是索引名字,第二個參數是索引的屬性的名字,第三個是一個options對象。通常是指定unique,設置索引是否惟一。
usersStore.createIndex("name", "name", { unique : false });
索引獲取數據
function indexGetData(){ var tx = db.transaction("users", READ_WRITE); var store = tx.objectStore("users"); var index = store.index("name"); var req = index.get("楊冪") req.onsuccess = function (evt) { console.debug("indexGet success" , evt.target.result); }; req.onerror = function (evt) { console.error("indexGet error:", evt.target.errorCode || evt.target.error); }; } function indexOpenCursor(){ var tx = db.transaction("users", READ_WRITE); var store = tx.objectStore("users"); var index = store.index("name"); var req = index.openCursor(); req.onsuccess = function (evt) { var cursor = evt.target.result; if(cursor){ //必要檢查 var value = cursor.value; console.log(value); cursor.continue(); //移動到下一項 } }; req.onerror = function (evt) { console.error("openCursor error:", evt.target.errorCode || evt.target.error); }; }
PS:索引用法跟普通取值和遊標取值同樣
對象存儲全部索引
function indexNames(){ var tx = db.transaction("users", READ_WRITE); var store = tx.objectStore("users"); var indexNames = store.indexNames; var index, i = 0, len = indexNames.length; while(i < len){ index = store.index(indexNames[i++]); console.log(index); } }
var request = indexedDB.deleteDatabase(name);
var request = indexedDB.deleteDatabase(name, options);
var DBDeleteRequest = window.indexedDB.deleteDatabase("toDoList"); DBDeleteRequest.onerror = function(event) { console.log("Error deleting database."); }; DBDeleteRequest.onsuccess = function(event) { console.log("Database deleted successfully"); console.log(event.result); // should be undefined };
dbInstance.deleteObjectStore(name);
var dbName = "sampleDB"; var dbVersion = 2; var request = indexedDB.open(dbName, dbVersion); request.onupgradeneeded = function(e) { var db = request.result; if (e.oldVersion < 1) { db.createObjectStore("store1"); } if (e.oldVersion < 2) { db.deleteObjectStore("store1"); db.createObjectStore("store2"); } // etc. for version < 3, 4... };
將手機與電腦鏈接到同一個網段,好比可使用wifi
查看本機ip地址,有時須要將本地鏈接禁用,查看ip地址的指令是ipconfig
在手機端使用瀏覽器查看結果以下:
這裏使用HBuilder打包成apk的安裝包,安裝打包結果以下:
文檔: http://dev.dcloud.net.cn/mui/ui/
源碼: https://github.com/dcloudio/mui/
6.3.一、Hello MUI
示例:
<!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>Hello MUI</title> <link href="css/mui.min.css" rel="stylesheet" /> </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">Hello MUI</h1> </header> <div class="mui-content"> <div class="mui-content-padded"> <button type="button" class="mui-btn">默認</button> <button type="button" class="mui-btn mui-btn-primary" id="btnHello">Hello</button> <button type="button" class="mui-btn mui-btn-success">綠色</button> <button type="button" class="mui-btn mui-btn-warning">黃色</button> <button type="button" class="mui-btn mui-btn-danger">紅色</button> <button type="button" class="mui-btn mui-btn-royal">紫色</button> </div> </div> <script src="js/mui.min.js"></script> <script type="text/javascript" charset="utf-8"> mui.init({ }); document.getElementById("btnHello").addEventListener("tap",function(){ mui.alert("Hello MUI!","提示","確認",function(){ mui.toast("關閉完成"); }); },false); </script> </body> </html>
效果:
代碼:
<!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>Hello MUI</title> <link href="css/mui.min.css" rel="stylesheet" /> </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">Hello MUI</h1> </header> <div class="mui-content"> <div class="mui-content-padded"> <button type="button" class="mui-btn">默認</button> <button type="button" class="mui-btn mui-btn-primary" id="btnHello">Hello</button> <button type="button" class="mui-btn mui-btn-success" id="btnWin">窗口</button> <button type="button" class="mui-btn mui-btn-warning">黃色</button> <button type="button" class="mui-btn mui-btn-danger">紅色</button> <button type="button" class="mui-btn mui-btn-royal">紫色</button> </div> </div> <script src="js/mui.min.js"></script> <script type="text/javascript" charset="utf-8"> mui.init({ //側滑關閉 swipeBack: true //Boolean(默認false)啓用右滑關閉功能 }); document.getElementById("btnHello").addEventListener("tap", function() { mui.alert("Hello MUI!", "提示", "確認", function() { mui.toast("關閉完成"); }); }, false); //mui加載完成 mui.ready(function() { mui(".mui-content").on("tap", "#btnWin", function() { mui.openWindow({ url: "sub1.html?id=1", id: "sub1.html", extras: { id: "1" }, createNew: false, //是否重複建立一樣id的webview,默認爲false:不重複建立,直接顯示 show: { autoShow: true //頁面loaded事件發生後自動顯示,默認爲true }, waiting: { autoShow: true, //自動顯示等待框,默認爲true title: '正在加載...' //等待對話框上顯示的提示內容 } }); }); }); </script> </body> </html>
效果:
示例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello List</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"> <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="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> <!--輪播--> <!--list--> <ul class="mui-table-view mui-table-view-chevron"> <li class="mui-table-view-cell mui-media"> <a class="mui-navigate-right" id="sub1.html"> <img class="mui-media-object mui-pull-left" src="images/cbd.jpg"> <div class="mui-media-body"> CBD <p class='mui-ellipsis'>烤爐模式的城,到黃昏,如同打翻的調色盤通常.</p> </div> </a> </li> <li class="mui-table-view-cell mui-media"> <a class='mui-navigate-right' id="index.html"> <img class="mui-media-object mui-pull-left" src="images/yuantiao.jpg"> <div class="mui-media-body"> 遠眺 <p class='mui-ellipsis'>靜靜的看這個世界,最後終於瘋了</p> </div> </a> </li> <li class="mui-table-view-cell mui-media"> <a class="mui-navigate-right"> <img class="mui-media-object mui-pull-left" src="images/shuijiao.jpg"> <div class="mui-media-body"> 幸福 <p class='mui-ellipsis'>能和心愛的人一塊兒睡覺,是件幸福的事情;但是,打呼嚕怎麼辦?</p> </div> </a> </li> </ul> <!--list--> </div> <div id="tabbar-with-chat" class="mui-control-content"> 添加 </div> <div id="tabbar-with-contact" class="mui-control-content"> 個人 </div> <div id="tabbar-with-map" class="mui-control-content"> 設置 </div> </div> </body> <script src="js/mui.min.js"></script> <script> mui.init({ swipeBack: true //啓用右滑關閉功能 }); mui("#slider").slider({ interval: 1000 }); mui.ready(function() { mui(".mui-content").on("tap", ".mui-navigate-right", function() { var id =this.id; mui.openWindow({ url: id, id: id, extras: { id: "1" }, createNew: false, //是否重複建立一樣id的webview,默認爲false:不重複建立,直接顯示 show: { autoShow: true //頁面loaded事件發生後自動顯示,默認爲true }, waiting: { autoShow: true, //自動顯示等待框,默認爲true title: '正在加載...' //等待對話框上顯示的提示內容 } }); }); }); </script> </html>
效果:
這裏使用HBuilder內置的MUI爲例,新增d06.html,頁面腳本以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>淘水果</title> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <!--標準mui.css--> <link rel="stylesheet" href="css/mui.min.css"> <!--App自定義的css--> <link rel="stylesheet" type="text/css" href="css/app.css" /> <style> .title { margin: 20px 15px 10px; color: #6d6d72; font-size: 15px; } .oa-contact-cell.mui-table .mui-table-cell { padding: 11px 0; vertical-align: middle; } .oa-contact-cell { position: relative; margin: -11px 0; } .oa-contact-avatar { width: 75px; } .oa-contact-avatar img { border-radius: 50%; } .oa-contact-content { width: 100%; } .oa-contact-name { margin-right: 20px; } .oa-contact-name, oa-contact-position { float: left; } </style> </head> <body> <header class="mui-bar mui-bar-nav"> <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> <h1 class="mui-title">淘水果</h1> </header> <nav class="mui-bar mui-bar-tab"> <a class="mui-tab-item mui-active" href="#tabbar"> <span class="mui-icon mui-icon-home"></span> <span class="mui-tab-label">暢銷水果</span> </a> <a class="mui-tab-item" href="#tabbar-with-chat"> <span class="mui-icon mui-icon-email"><span class="mui-badge">9</span></span> <span class="mui-tab-label">新貨上架</span> </a> <a class="mui-tab-item" href="#tabbar-with-contact"> <span class="mui-icon mui-icon-contact"></span> <span class="mui-tab-label">收款</span> </a> <a class="mui-tab-item" href="#tabbar-with-map"> <span class="mui-icon mui-icon-gear"></span> <span class="mui-tab-label">發貨</span> </a> </nav> <div class="mui-content"> <div id="tabbar" class="mui-control-content mui-active"> <div id="slider" class="mui-slider"> <div class="mui-slider-group mui-slider-lhttp://127.0.0.1:8020/HTML5_2_1/d06.html#oop"> <!-- 額外增長的一個節點(循環輪播:第一個節點是最後一張輪播) --> <div class="mui-slider-item mui-slider-item-duplicate"> <a href="#"> <img src="images/yuantiao.jpg"> </a> </div> <!-- 第一張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/shuijiao.jpg"> </a> </div> <!-- 第二張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/muwu.jpg"> </a> </div> <!-- 第三張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/cbd.jpg"> </a> </div> <!-- 第四張 --> <div class="mui-slider-item"> <a href="#"> <img src="images/yuantiao.jpg"> </a> </div> <!-- 額外增長的一個節點(循環輪播:最後一個節點是第一張輪播) --> <div class="mui-slider-item mui-slider-item-duplicate"> <a href="#"> <img src="images/shuijiao.jpg"> </a> </div> </div> <div class="mui-slider-indicator"> <div class="mui-indicator mui-active"></div> <div class="mui-indicator"></div> <div class="mui-indicator"></div> <div class="mui-indicator"></div> </div> </div> <ul class="mui-table-view mui-table-view-chevron" id="goodsList"> </ul> </div> <div id="tabbar-with-chat" class="mui-control-content"> <p> <label for="name">名稱:</label> <input type="text" id="name" value="" /> </p> <p> <label for="price">價格:</label> <input type="text" id="price" value="" /> </p> <p> <input type="hidden" id="goodsId" /> <button id="btnInsert">添加</button> <button id="btnUpdate">更新</button> </p> </div> <div id="tabbar-with-contact" class="mui-control-content"> <div class="title">這是div模式選項卡中的第3個子頁面,該頁面展現一個通信錄示例.</div> <ul class="mui-table-view mui-table-view-striped mui-table-view-condensed"> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">葉文潔</h4> <span class="oa-contact-position mui-h6">董事長</span> </div> <p class="oa-contact-email mui-h6"> yewenjie@sina.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">艾AA</h4> <span class="oa-contact-position mui-h6">總經理</span> </div> <p class="oa-contact-email mui-h6"> aaa@163.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">羅輯</h4> <span class="oa-contact-position mui-h6">員工</span> </div> <p class="oa-contact-email mui-h6"> luoji@126.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">雲天明</h4> <span class="oa-contact-position mui-h6">員工</span> </div> <p class="oa-contact-email mui-h6"> ytm@163.com </p> </div> </div> </div> </li> <li class="mui-table-view-cell"> <div class="mui-slider-cell"> <div class="oa-contact-cell mui-table"> <div class="oa-contact-avatar mui-table-cell"> <img src="images/60x60.gif" /> </div> <div class="oa-contact-content mui-table-cell"> <div class="mui-clearfix"> <h4 class="oa-contact-name">史強</h4> <span class="oa-contact-position mui-h6">員工</span> </div> <p class="oa-contact-email mui-h6"> shiqiang@gmail.com </p> </div> </div> </div> </li> </ul> </div> <div id="tabbar-with-map" class="mui-control-content"> <div class="title">這是div模式選項卡中的第4個子頁面,該頁面展現一個常見的設置示例.</div> <ul class="mui-table-view"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 新消息通知 </a> </li> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 隱私 </a> </li> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 通用 </a> </li> </ul> <ul class="mui-table-view" style="margin-top: 25px;"> <li class="mui-table-view-cell"> <a class="mui-navigate-right"> 關於mui </a> </li> </ul> <ul class="mui-table-view" style="margin-top: 25px;"> <li class="mui-table-view-cell"> <a style="text-align: center;color: #FF3B30;"> 退出登陸 </a> </li> </ul> </div> </div> </body> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/mui.min.js"></script> <script> //定義當前應用的對象 var dbApp = { //打開數據庫 openDb: function() { //建立名稱爲products,版本爲1.0,描述爲產品數據庫,3M大小的數據庫 this.db = openDatabase("products", 1.0, "產品數據庫", 1024 * 1024 * 3, function() { this.log("建立或打開數據庫完成"); }); }, //初始化 init: function() { //打開或建立數據庫 this.openDb(); //綁定事件 this.bindEvent(); //展現數據 this.select(); this.log("初始化完成"); }, //綁定事件 bindEvent: function() { //添加事件 $("#btnInsert").click(this.insert); $("#btnUpdate").click(this.update); $("#btnCreateTable").click(this.createTable); $("#btnDropTable").click(this.dropTable); }, //顯示消息 log: function(info) { mui.toast(info); }, //執行sql的通用方法 result.rowsAffected 影響行數 //callback執行成功時的回調方法 exeSql: function(sql, title, param, callback) { title = title || "操做"; this.db.transaction(function(tx) { tx.executeSql( sql, param || [], function(tx, result) { dbApp.log(title + '成功'); if(callback) { //若是有參數 callback(result); } }, function(tx, error) { dbApp.log(title + '失敗' + error.message); }); }); }, //建立表 createTable: function() { dbApp.exeSql("create table IF not EXISTS goods(id integer primary key autoincrement,name text not null,price double)", "建立表"); }, //刪除表 dropTable: function() { dbApp.exeSql("drop table IF EXISTS goods", "刪除表"); }, //展現,加載數據 select: function() { dbApp.exeSql("select id,name,price from goods", "查詢", [], function(result) { //將表格中tr索引大於0的元素刪除 $("#goodsList li").remove(); for(var i = 0; i < result.rows.length; i++) { var tr = $("<li class='mui-table-view-cell mui-media'><a class='mui-navigate-right'><img class='mui-media-object mui-pull-left' src='images/cbd.jpg'><div class='mui-media-body'>" + result.rows.item(i)["name"] + "<p class='mui-ellipsis'>新鮮好吃的水果,僅售:" + result.rows.item(i)["price"] + "/斤</p></div></a></li>") tr.appendTo("#goodsList"); } mui.init({ swipeBack: true //啓用右滑關閉功能 }); }); }, //插入數據 insert: function() { //若是insert方法被綁定爲事件,則this表示事件發生的對象 dbApp.exeSql("insert into goods(name,price) values(?,?)", "添加", [$("#name").val(), $("#price").val()], function() { dbApp.select(); }); }, //刪除 del: function(id, link) { dbApp.exeSql("delete from goods where id=?", "刪除", [id], function(result) { //查找a標籤最近的一個tr父元素,移除 $(link).closest("tr").remove(); }); }, //編輯 edit: function(id) { dbApp.exeSql("select id,name,price from goods where id=?", "編輯", [id], function(result) { $("#name").val(result.rows.item(0)["name"]); $("#price").val(result.rows.item(0)["price"]); $("#goodsId").val(result.rows.item(0)["id"]); dbApp.log("修改後請保存"); }); }, //更新 update: function() { if($("#goodsId").val()) { dbApp.exeSql("update goods set name=?,price=? where id=?", "更新", [$("#name").val(), $("#price").val(), $("#goodsId").val()], function(result) { dbApp.select(); $("#goodsId").val(""); }); } else { dbApp.log("請選擇要更新的記錄 "); } } }; dbApp.init(); </script> </html>
打包運行後的結果以下:
https://git.coding.net/zhangguo5/HTML5_143.git
https://coding.net/u/zhangguo5/p/HTML502/git
github: https://github.com/zhangguo5/HTML5_2_1
mui示例: https://git.coding.net/zhangguo5/GoMallPro.git
https://www.bilibili.com/video/av16293468/
9.1.一、重現每一個上課示例。
9.1.二、用戶登陸,記住密碼,選擇顏色,下次打開頁面時不須要輸入密碼,將背景色設置爲用戶選擇的顏色。Login.html,Admin.html
9.1.三、用SessionStorage判斷用戶是否登陸,若是未登陸轉到頁面Login.html
9.1.四、使用IndexedDb完成以下功能:
參考:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDB-UI</title> </head> <body> <h2>IndexedDB-UI(NOSQL)</h2> <table border="1" cellspacing="1" cellpadding="1" id="tabGoods" width="100%"> <tr> <th>序號</th> <th>編號</th> <th>名稱</th> <th>價格</th> <th>操做</th> </tr> </table> <fieldset> <legend>商品信息</legend> <p> <label for="id">編號</label> <input type="text" name="id" id="id" value="" /> </p> <p> <label for="name">名稱</label> <input type="text" name="name" id="name" value="" /> </p> <p> <label for="price">價格</label> <input type="number" name="price" id="price" value="" /> </p> <p> <input type="button" id="btnSubmit" value="添加" /> <input type="button" id="btnUpdate" value="更新" /> </p> </fieldset> <h3 id="msg"></h3> <script src="../js/jQuery/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script> //數據庫 var db; function init() { create(); $("body").on("click", "#btnSubmit", {}, function() { add(); }); $("#tabGoods").on("click", ".del", {}, function() { if(confirm('您肯定要刪除嗎?')) { var tr = $(this).closest("tr"); del(tr.data("goods").id, function() { alert('刪除成功!'); tr.remove(); }); } }); $("#tabGoods").on("click", ".edit", {}, function() { var tr = $(this).closest("tr"); var obj = tr.data("goods"); $("#id").val(obj.id).prop("disabled", "disabled"); $("#name").val(obj.name); $("#price").val(obj.price); }); $("body").on("click", "#btnUpdate", {}, function() { var obj = { "id": $("#id").val(), "name": $("#name").val(), "price": $("#price").val() }; edit(obj, function() { alert('修改爲功!'); getAll(); }); $("#id").val(obj.id).removeProp("disabled"); }); } init(); //建立數據庫與表 function create() { //建立一個名稱爲gomall且版本爲2的數據庫,返回一個請求 var request = indexedDB.open("gomallPro", 2); //綁定回調事件,成功時 request.onsuccess = function(e) { db = e.target.result; log('建立數據庫或打開數據庫成功!'); getAll(); }; //失敗時 request.onerror = function(e) { log("錯誤:" + e.target.errorCode || e.target.error); }; //增長數據庫版本號時,會觸發onupgradeneeded事件(會在onsuccess以前被調用) request.onupgradeneeded = function(e) { //建立對象存儲空間(ObjectStore),相似表,goods是表名,id是主鍵,存儲的是JSON e.target.result.createObjectStore("goods", { "keyPath": "id" }); log("初始化數據庫成功!"); }; } //新增數據 function add() { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //javascript中的對象數組 var item = { "id": $("#id").val(), "name": $("#name").val(), "price": $("#price").val() }; goods.add(item); log("添加數據成功!"); getAll(); } //更新對象 function edit(item, callback) { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //執行更新 var request = goods.put(item); request.onsuccess = function(e) { log(e.target.result); if(callback) callback(); }; } //刪除對象 function del(key, callback) { //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //執行刪除操做 var request = goods.delete(key); //成功時的回調 request.onsuccess = function(e) { log(e.target.result); log("刪除成功!"); if(callback) callback(); }; } var index; //得到多個對象(遊標) function getAll() { index = 1; //移除表格中除第一行之外的全部行 $("#tabGoods tr:gt(0)").remove(); //建立事務對象 var tx = db.transaction("goods", "readwrite"); //從數據庫中得到存儲對象,表 var goods = tx.objectStore("goods"); //打開遊標 var request = goods.openCursor(); //成功時的回調 request.onsuccess = function(e) { //得到遊標 var cursor = e.target.result; if(cursor) { //若是不爲空 var obj = cursor.value; genTr(obj); //下移 cursor.continue(); } }; } function genTr(goods) { var tr = $("<tr/>").data("goods", goods); $("<td/>").html(index++).appendTo(tr); $("<td/>").html(goods.id).appendTo(tr); $("<td/>").html(goods.name).appendTo(tr); $("<td/>").html(goods.price).appendTo(tr); var btnDel = $("<input type='button' value='刪除' class='del'/>"); var btnEdit = $("<input type='button' value='編輯' class='edit'/>"); $("<td/>").append(btnDel).append(btnEdit).appendTo(tr); tr.appendTo($("#tabGoods")); } //顯示消息 var msg = document.getElementById("msg"); function log(m) { msg.innerHTML += m + "<br/>"; } </script> </body> </html>
運行結果:
9.2.一、完成一個密碼管理器APP
javascript獲取url中的參數
//方法一:採用正則表達式獲取地址欄參數 function GetQueryString(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if(r!=null)return unescape(r[2]); return null; }