TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
最近在做在线考试系统时遇到这样一个问题,就是当考生考试时可能出出现断网、关闭浏览器,刷新等问题,此时数据又没有实时写入数据库,所以造成数据丢失问题,,所以这里就需要用到本地存储,一开始想到的是用cookie,但是cookie缺失太小了是有4k。
$ K" c p# s) y! V% b 本地持久化存储一直是本地客户端程序优于 web 程序的一个方面。对于本地应用程序,操作系统会一共一个抽象层,用于存储和获取特定于应用程序的数据,例如用户设置或者运行时状态。这些值可以被存储于注册表、INI 文件,或者其他什么地方,这取决于操作系统的实现。如果你的本地应用程序需要不简单是键值对形式的本地存储,你也可以使用嵌入式数据库、发明你自己的文件格式,或者其他很多种解决方案。4 ], l0 B+ _# i3 J
UserData实现方式:: A7 F7 k) |5 a. W) e F' @# d
userData行为通过将数据写入一个UserData存储区(UserDatastore)来保存数据,userData可以将数据以XML格式保存在客户端计算机上,如果你用的是 Windows 2000 或者 Windows XP,是保存在C:\Documents and Settings\Liming\UserData\文件夹下(如果操作系统不是安装在C盘,那么C就应该是操作系统所在的分区)。
) {7 B* I3 M; P 该数据将一直存在,除非你人为删除或者用脚本设置了该数据的失效期。4 u0 |7 v. h) M1 e( ~# F. C" S: a
userData行为提供了一个比Cookie更具有动态性和更大容量的数据结构。每页的UserData存储区数据大小可以达到64 Kb,每个域名可以达到640 Kb。7 s" @+ e; e$ Y0 V d3 J
userData行为通过sessions为每个对象分配UserData存储区。使用save和load方法将UserData存储区数据保存在缓存(cache)中。一旦UserData存储区保存以后,即使IE浏览器关闭或者刷新了,下一次进入该页面,数据也能够重新载入而不会丢失。* ?* g$ O$ Z, L& {- O2 K* d
但是,UserData是IE的东西,所以其他浏览器不兼容。
s& n" @$ O" p: GHTML5 storage实现方式:* a; u8 P- v, k8 o8 s
HTML5 storage提供了一种方式让网站能够把信息存储到你本地的计算机上,并再以后需要的时候进行获取。这个概念和cookie相似,区别是它是为了更大容量存储设计的。Cookie的大小是受限的,并且每次你请求一个新的页面的时候cookie都会被发送过去。HTML5的storage是存储在你的计算机上,网站在页面加载完毕后可以通过javascript来获取这些数据。
' c7 k4 R0 j9 t
4 W! l/ g1 K6 h# w* E' i; N% m: K 由于HTML5 storage IE8一下浏览器 所有IE8一下版本要做判断使用UserData的方式实现。具体代码已封装。说明一下 jQuery.browser建议弃用,可以使用jQuery.support来代替。
2 E& ~# s% `9 ~4 _8 y a/ G3 _页面展示:# q9 u3 I7 y7 ]6 [ _
$ g* a, c i) k: m$ [& m! D" w5 @- \. g0 [
- <!doctype html>) D# }) N, `4 U/ B0 N
- <html>
: u6 |6 ~% q% O* u. D/ z$ Z- ~ - <head>
5 j: ]0 ]; c: @+ g! z6 t - <title>科帮网在线考试本地存储Powered by 52itstyle</title>% {1 f) N4 R9 T( R/ T# [; G
- <meta charset="utf-8" />
! G( k9 ~3 h0 m5 T, Q - <script src="../js/jquery-1.8.3.js"></script>
2 K4 V4 `) y0 B y - <script src="../js/localstorage.js"></script>
/ |$ P+ h1 {) \: m7 T, U - <script src="../js/jquery.utils.js"></script>
" v- Q1 z% b! E3 { - <script type="text/javascript">
- S% c, G# G- T' z' v! b - var studentID = "007";
( N; F4 ]8 x7 E6 @7 C1 O - var ExamID = "52itstyle";8 X0 i5 ?, c! U1 A' Q
- var quesNumber = 3;, N! B1 U$ \& J. R8 [/ C
- $(function(){
* M* y1 W: _% @' g: I; v; P5 } - showQuestion();
. q% \3 @- ]# j. }9 d' y6 Z W - $("input").click(function(){+ k3 S* ~) Y5 L: H* k
- var QuestionID = $(this).attr("name");
% R4 i2 d- ^/ ]* h. U) ^ - var ExamAnswer = $(this).val();
6 M1 o) m# h$ R - qext.LocalStorage.save(studentID,ExamID,QuestionID,ExamAnswer);1 ]/ e/ i: d6 ^4 V4 u3 Q
- });) N/ z/ G5 }& P; V: ^
- });
|4 ^3 s5 v% _ f$ s: e - /**5 v% B. l- v1 c3 A8 h' ~& v- |& V
- * 读取本地存储答案并展示(科帮网http://www.52itstyle.top)
4 k+ Z R' i4 T' B* F - * java爱好者QQ群:26490602
4 T1 t) _4 \( m+ w - *// w+ d* @6 o, ~
- function showQuestion(){; Z- w* I3 Q5 L" ^7 c
- for(var i=1;i<=quesNumber;i++){
, ?2 J# Y) T6 z* P - var rst = getPerQuesInfo(i);9 J. \. s6 Y5 k* d4 l
- if(null!=rst){% d% H2 z/ U8 J: r) [9 o/ J# ?
- var obj = eval("("+rst+")"); " j3 E% {6 t. ] }, K
- var examAnswer = obj.ExamAnswer; V+ S* @$ k, q, X
- $("input[name="+i+"]").val(examAnswer)
8 x3 M* d. `; e) ~2 Y4 @6 W - }/ } j4 Z) X& [+ s6 J! |
- }) d* M( v" D1 Y1 q
- }& @4 b# {% k' I# r. h& {) b
- /**9 k7 ^8 b" g) a: t/ i5 p( G
- * 获取单个试题信息(科帮网http://www.52itstyle.top)8 X1 @$ d. N/ K' s
- * java爱好者QQ群:264906027 E! C) i3 m. Z! \
- */" ~7 W9 l1 {- g, E8 C2 d
- function getPerQuesInfo(QuestionID){
5 `$ ~. o% }) v- b) Q- }3 ]0 L - var examKey = studentID+ExamID+QuestionID;& e% V b) G, o" a ?; |8 t6 v
- var rst = qext.LocalStorage.get({
( k8 n# \- T: M3 k - key : examKey' s2 K8 _9 ^; _, F0 x! d
- });
: B. H2 W) `+ }' F - return rst;4 T1 h5 e, t7 C0 C
- }
- _$ v' l% ?8 y$ j0 i& J% z* h+ i - </script>
4 s' `5 j+ X# m" {9 M- [6 N - </head>
+ B( r' F! p( D1 K - <body># R/ h$ V4 k2 l9 c8 L6 U
- <div id="1">成吉思汗有几个老婆?</div>9 g, r3 S' Y% w* D
- <div># l& F( i [+ s& t0 r) [
- <input type="radio" value="A" name="1" />A 1
' Y) N$ G* D) M - <input type="radio" value="B" name="1"/>B 2
i5 ^: o/ Y" { - <input type="radio" value="C" name="1"/>C 3
" H8 y8 d# v' ]9 O - <input type="radio" value="D" name="1"/>D 4
) q! B8 f! X3 B! m6 k; y - </div>3 j; \$ |3 V! \$ _8 u" ~, W
- <div>成吉思汗有几个老婆?</div>
+ W7 _8 Z. F% `1 A - <div>
3 S7 h4 c& a( u6 q$ ^3 t - <input type="radio" value="A" name="2" />A 13 b1 Y3 Z3 G6 @" q
- <input type="radio" value="B" name="2"/>B 2 ) ^$ W/ }: u6 r( V9 X
- <input type="radio" value="C" name="2"/>C 3
2 |: K7 b! N* s& ~ `( z - <input type="radio" value="D" name="2"/>D 43 G) s$ d1 C0 I( q
- </div>; Y7 K3 D R$ o- l
- <div>小伟有几个老婆?</div> B, o9 i7 f4 I; e7 S; e5 w
- <div>
6 e$ l5 _% W7 a$ t2 u- y3 y - <input type="radio" value="A" name="3" />A 1
$ B# L4 C0 g/ E8 \ - <input type="radio" value="B" name="3"/>B 2 ! p% Q: B0 e' V F
- <input type="radio" value="C" name="3"/>C 3
4 I1 F) U0 X7 F3 t0 a$ n3 Y - <input type="radio" value="D" name="3"/>D 无数1 u9 [5 x/ |9 s5 G& G4 ^
- </div>
. `5 \ }6 v k/ o y - <a href="http://www.52itstyle.top/">传送门</a>
1 U5 Y9 q1 S! r - </body>
. S) P0 c+ Z/ o, E3 [: R - </html>
复制代码 本地存储JS封装:localstorage.js 不得不佩服此人的代码掉渣天。3 P. C- B- g4 Q- I
- /**; a+ I. M' z/ [% h
- * 注册命名空间8 ?) B( v! R5 G: ?6 J
- * @param {String} fullNS 完整的命名空间字符串,如qui.dialog3 q# D+ w" f# \+ N5 a8 E3 A6 N
- * @param {Boolean} isIgnorSelf 是否忽略自己,默认为false,不忽略
( y! s3 F: r8 u# i - * @author zhaoxianlie(xianliezhao@foxmail.com)
7 W/ O. F ?/ L" j- a5 r# j - * @example
: k9 x T0 `9 |4 k( e" @4 G - * window.registNS("QingFeed.Text.Bold");! N3 `1 s5 t( {( J1 L0 M
- */
2 v+ {2 `0 Q' o+ k" A' K/ s - window.registNS = function(fullNS,isIgnorSelf){
9 _7 O. c) o Q! _! I3 B - //命名空间合法性校验依据
5 X- u. k7 [, |2 n9 z8 C* s - var reg = /^[_$a-z]+[_$a-z0-9]*/i;
. T' B8 G" q8 @% F -
6 M7 \' {: X0 `( c - // 将命名空间切成N部分, 比如baidu.libs.Firefox等
! P) T6 Q6 n. G9 Y9 {5 v - var nsArray = fullNS.split('.');) P$ ?, P/ Y" O3 r
- var sEval = "";! `' j, c; s6 Z
- var sNS = "";5 O( c; S+ s0 _' N# p% C
- var n = isIgnorSelf ? nsArray.length - 1 : nsArray.length;
U# B) N- Z6 _ - for (var i = 0; i < n; i++){
% \' t( p6 F1 Z# k. D v8 P - //命名空间合法性校验
' J) }1 a, u- s+ m' e - if(!reg.test(nsArray[i])) {
5 E; m+ y% \; e9 S0 D) ~ - throw new Error("Invalid namespace:" + nsArray[i] + "");
5 \! ]1 f/ D4 J7 I9 X - return ;
/ ?, S; `& G' R) J - }# o" D, X7 e0 @! j v# E- o+ @
- if (i != 0) sNS += ".";
' {4 j2 {' I; J. {0 }1 m& t: ` - sNS += nsArray[i];
8 J& j! Y: R+ ?" }; \0 n$ K - // 依次创建构造命名空间对象(假如不存在的话)的语句4 [6 C# Y! `- D0 V
- sEval += "if(typeof(" + sNS + ")=='undefined') " + sNS + "=new Object();else " + sNS + ";";
7 F. `3 V/ u, H1 [ - }7 f, |7 s; l$ Q6 I* r% Q
- //生成命名空间& n, l: x. V5 D) }5 C& ]( s
- if (sEval != "") {
5 Y% ^7 ^- U. J( H( s - return eval(sEval);
8 X2 A) M3 h* U1 b# L5 E - }
, t" i$ j: a0 D. w& L# `2 c - return {};6 [7 ]8 B7 T+ z* d$ P3 r) @
- };0 I0 K& d4 E: K8 j4 J# `, g
- 1 O0 `/ z4 a; e/ Y$ w
4 f! @+ C C0 T4 P- /**) W i- N/ ?7 z, e, g+ o9 r) I
- * 注册命名空间
`9 |: m1 F7 u3 m* J5 N - */
' y, f( {. u; l - window.registNS('qext');) q2 b3 |/ _. X; Y& C
8 x ^% p" K' |6 ~" p% M1 g8 `% }2 o- /**
9 e( L" d8 N3 E. s! D4 u/ u9 } - * @class qext.LocalStorage3 L8 X6 T, _ f1 x: ]- p. p9 F
- * 跨浏览器的本地存储实现。高级浏览器使用localstorage,ie使用UserData。虽然说是本地存储,也请不要存储过大数据,最好不要大于64K.8 H* |' X" c% ^% o2 H
- * 因为ie下UserData每页最大存储是64k。
2 b# o; v p4 b& b - * @singleton
1 u |7 Q! `1 V# ? - * @author zhaoxianlie (xianliezhao@foxmail.com)
5 P( _9 M; a+ _$ B0 N7 M - */
7 Z g8 o" {( k$ c8 d% h - (function(){; l5 [+ y% O# d- [
- /**- {$ q, n8 ~$ a5 x
- * 验证字符串是否合法的键名6 o" p5 U' P; u: }/ m- n
- * @param {Object} key 待验证的key
5 P2 d. f4 a5 R0 T! Q - * @return {Boolean} true:合法,false:不合法
& j' A: |% s$ m) u - * @private
s/ I2 i, ]% \: f1 {% | - */0 v* ]7 W3 S- B2 J- s& r. t8 R
- function _isValidKey(key) {2 E6 A- I6 ?# V, m1 ~5 q
- return (new RegExp("^[^\\x00-\\x20\\x7f\\(\\)<>@,;:\\\\\\"\\[\\]\\?=\\{\\}\\/\\u0080-\\uffff]+\x24")).test(key);# y; b' V' R5 F) }1 p
- }
4 z/ D/ U) p6 z9 d# w* P( ]. L -
1 i* \: q. v/ m7 X) ~7 [' c - //所有的key
0 N& K( H/ I" M' M - var _clearAllKey = "_baidu.ALL.KEY_";
4 x5 d' p0 _: M- c -
. T# `! Y* {* K - /**
- r8 U3 z8 {7 g! k' [ - * 创建并获取这个input:hidden实例0 Z" R. ?7 z, Y" C9 z8 ~: B6 r1 ~5 y
- * @return {HTMLInputElement} input:hidden实例
a8 h% F! z8 s5 ?$ D1 Z - * @private8 o) r# O4 z- ]7 j3 I
- */
$ `& M% @6 E0 g7 n& e - function _getInstance(){2 d' ~0 g1 Y! Y% j5 t; N' P
- //把UserData绑定到input:hidden上) [/ }9 _# t2 Z7 x2 }2 W9 e
- var _input = null;
2 r# E( I8 \5 w8 f$ q - //是的,不要惊讶,这里每次都会创建一个input:hidden并增加到DOM树种. J, ~& O5 r# e) }
- //目的是避免数据被重复写入,提早造成“磁盘空间写满”的Exception6 ?9 n% @. Y/ j/ L
- _input = document.createElement("input");
: ]; [: p7 t+ l5 A) L - _input.type = "hidden";+ k6 m+ q7 z3 A6 t3 r f
- _input.addBehavior("#default#userData");
5 h- G" L4 _$ d9 [ Q2 R - document.body.appendChild(_input); $ X, X$ @ e( d+ R! m) r$ i
- return _input;& P2 W1 ^# r. E) b
- }3 Z& S# X9 Y/ X6 f
- 7 L& i e% g% g
- /**
& g4 w- e6 f/ ]. F# x6 X - * 将数据通过UserData的方式保存到本地,文件名为:文件名为:config.key[1].xml
4 E. O9 M! Y( G/ h; y2 n - * @param {String} key 待存储数据的key,和config参数中的key是一样的3 K% O( c+ X' w1 y( ^1 p' m
- * @param {Object} config 待存储数据相关配置
# A- h; l' D1 e* B3 { - * @cofnig {String} key 待存储数据的key
' u1 U- g3 {: |6 B& f - * @config {String} value 待存储数据的内容5 r! \: S8 C7 j. S1 n+ ~7 _0 Y
- * @config {String|Object} [expires] 数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间3 |% m' H0 O% f* E& o* K! I% o
- * @private# g' h; i. {0 f
- */
& M) \+ a- E, o0 F8 R- Z - function __setItem(key,config){
9 F% ^9 K7 p5 ?9 d - try {
j8 X+ P/ c) X# o1 l# `+ m0 | - var input = _getInstance();. v1 j X( z, _
- //创建一个Storage对象, z: u6 ]. b+ R3 z! @- F7 ?' {7 G
- var storageInfo = config || {};
2 \9 {1 ]- d4 u; M) R; A) p. R - //设置过期时间
7 {6 n% [7 _+ K1 o* C) o - if(storageInfo.expires) {. W" w7 Q# o7 `* }( [3 l/ S2 n
- var expires;" l( M# ]- w0 d8 Y
- //如果设置项里的expires为数字,则表示数据的能存活的毫秒数( ]+ u; L% }7 v. v. W
- if ('number' == typeof storageInfo.expires) {
) C0 \5 i- @( y* h - expires = new Date();
, i& Y$ N) q% I4 N: M - expires.setTime(expires.getTime() + storageInfo.expires);
: Z: [! U( ]# O" J! J - }- z1 Y, b# |4 B* y+ b
- input.expires = expires.toUTCString();+ v7 B; Y& g) r' E2 N
- }
5 }" ]3 t9 j# I! d% w -
3 T; Z$ q+ E4 u+ k5 z: C% v/ x {' d - //存储数据3 b8 X2 {8 t: N, `/ W0 r
- input.setAttribute(storageInfo.key,storageInfo.value);1 P c- Q: x u W+ W
- //存储到本地文件,文件名为:storageInfo.key[1].xml
_: N G7 G, Y; h i5 g" S - input.save(storageInfo.key);
, R. [+ R' Q$ @3 H; k - } catch (e) {7 |; j9 U5 l$ k# g
- }! V# F- M" v# f8 I) b
- }
Z# D. B" o7 S' M7 c
+ I2 B. l* F1 g- /**/ z' J& s- M2 r. k
- * 将数据通过UserData的方式保存到本地,文件名为:文件名为:config.key[1].xml
- u+ i4 M( B7 B+ N9 u - * @param {String} key 待存储数据的key,和config参数中的key是一样的
- L( V+ R. F& l" v. O# h/ c! s - * @param {Object} config 待存储数据相关配置" B; J- c. j; W9 z7 x* R/ s e4 c
- * @cofnig {String} key 待存储数据的key8 l) X/ ]% u5 }: F7 l' o
- * @config {String} value 待存储数据的内容
" R, B5 W3 N+ I. Z e - * @config {String|Object} [expires] 数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间
% w [9 G( \+ W3 }: j8 x - * @private
% g& L! {* d+ g, [6 t0 n - */
/ O U- p7 B1 U/ P) \ - function _setItem(key,config){
) T( O9 T1 ]0 @% ] - //保存有效内容
6 r% Q8 V. v! M$ y- U3 H4 q# _ - __setItem(key,config);
& S7 s+ e% ]1 u! ^ -
; a$ h0 W, z7 r- M3 T5 B8 Y - //下面的代码用来记录当前保存的key,便于以后clearAll
8 c4 h9 |5 U9 ~5 A* E - var result = _getItem({key : _clearAllKey});( D, ]; w8 p6 [3 C9 W ?! E' i3 m, U
- if(result) {
8 f+ q% J, \# f# C8 M! v, @ - result = {$ N Y `) g" B5 `7 D/ c+ y. K
- key : _clearAllKey,4 S; ^6 d8 ~9 p; t" @" K: o' O+ q
- value : result ; I: I Y$ [; h7 k5 l
- };1 a T+ n! b- e; a
- } else {
1 Q1 V# r; i- V5 u2 t - result = {9 q$ N* |( w7 ^: F% O* G' x
- key : _clearAllKey,4 j; h# E! \9 U
- value : ""
: L& L' u1 k7 v( ~6 _ - };
$ b! U* B$ a" q8 ~9 \+ r$ h* {( e - }$ U% E+ z1 f) s, ^) X! A
- 1 R2 k! ~, c: F- M4 M# t" D
- if(!(new RegExp("(^|\\|)" + key + "(\\||$)",'g')).test(result.value)) {' ?7 A- Q f$ G& _3 D
- result.value += "|" + key;+ w" c* p* W% d/ Z# K2 e% R6 O H" h
- //保存键
2 `0 X) F8 P- `5 X: U1 s7 i( n - __setItem(_clearAllKey,result); 1 K3 o% s7 |" O
- }
4 K- @$ w2 T* M8 z4 ]) ~ - }
' N2 e- P% f( w9 B( u - 2 C# c- s% N" V) m; I
- /**
' q0 Q1 H7 x* ?6 G( @ C3 z - * 提取本地存储的数据
" T0 R, ]/ |) {7 X0 g - * @param {String} config 待获取的存储数据相关配置
& [8 T2 p1 W. X$ J2 C0 H5 K: N - * @cofnig {String} key 待获取的数据的key& N* q/ H) [' J" ^2 Q
- * @return {String} 本地存储的数据,获取不到时返回null; c* W- Q3 \0 t( ^
- * @example & F% L8 p8 A% K& m$ F( S
- * qext.LocalStorage.get({0 Y! ^/ L# ~+ z3 g2 p" ?
- * key : "username"7 O `# \$ J1 |4 K6 v& U& F
- * });/ k) S5 ]8 X1 t' C8 H$ E
- * @private
* A- a& g8 m' X( x - */3 ^# i9 K/ _* B
- function _getItem(config){: f% u# B/ g6 E- X% d
- try {
7 k+ s. m+ i h$ F# q - var input = _getInstance();7 ]2 I& e1 J* ^* \" [
- //载入本地文件,文件名为:config.key[1].xml: E; o6 L" r; j* M- a. U* E/ v
- input.load(config.key);/ X4 d% ?+ ~/ ]2 D! z- C) k# ^
- //取得数据
8 @0 q, k( s- C0 z' q, ^ - return input.getAttribute(config.key) || null;
% O2 { x6 [" q - } catch (e) {0 Q5 d) I0 H% B$ W1 }5 _& b/ o( H
- return null; ! }( p7 b! C3 I- j" x% [* Z) q
- }9 W& Z3 P2 _6 T2 Z
- }8 K3 h$ G% @2 D( S4 I) r
-
9 ^% J2 _# ~- S3 @/ e$ D6 O: H: z2 g - /**
3 {8 \) `0 F* |: K' v6 U - * 移除某项存储数据( y' V2 @$ B6 J0 I3 y0 W
- * @param {Object} config 配置参数
* [, U9 f) a# P0 K& ] - * @cofnig {String} key 待存储数据的key
3 a) D/ g, b# I# K) f+ l0 M! w - * @private
% v% s: b- J; b" D8 U' w% ` - */
. Z: B% k6 i8 B& Q4 w - function _removeItem(config){; P8 j% v3 i, U& p! f
- try {
- m+ d. E. }4 Z8 y - var input = _getInstance();
" l/ R4 R I1 w% X4 x - //载入存储区块
' i2 ^) r7 b7 l* P - input.load(config.key);
1 K6 b2 p5 r& c+ X* w% l# L# o - //移除配置项$ V3 p; A: G; E! Y8 \
- input.removeAttribute(config.key);
& B4 o* z+ M8 ~6 R8 s8 z5 l - //强制使其过期8 n2 M! Z: p4 {6 d# l3 s
- var expires = new Date();9 D. `% E* b! A- U d7 _
- expires.setTime(expires.getTime() - 1);
" s4 \7 e+ Z: |" r2 u - input.expires = expires.toUTCString();* x* s: _- Z p* N, n, V
- input.save(config.key);
- @' E8 y6 @- w. ]$ D - 4 E4 c" }2 F- M6 k6 @
- //从allkey中删除当前key
- h! n9 X8 }2 p - //下面的代码用来记录当前保存的key,便于以后clearAll
& a ^4 ~3 r' p - var result = _getItem({key : _clearAllKey});
& g- }% ?9 ?# [0 g" Q6 T - if(result) {( f4 V" s# y( Q z# t( Q
- result = result.replace(new RegExp("(^|\\|)" + config.key + "(\\||$)",'g'),'');( R0 g. f4 u+ G& H' R' i4 O3 u
- result = {# W" X" N* O* d R8 M* \5 p5 s, L
- key : _clearAllKey,
; Z( j0 u0 i. C" Q! W4 P - value : result . h3 s0 n Z: n, x
- };( S& m2 k, J1 F6 C, J! y8 ^
- //保存键, |7 i) @* W4 {( q* |" y% q
- __setItem(_clearAllKey,result); 3 y* s g! ^; T2 _
- }
1 u, [# X6 e: o, |- ? -
$ J U6 d9 n+ r# v, B2 |& { - } catch (e) {
' O7 J3 k+ Q9 T5 c3 g% p - }; P* T* d3 ]$ t) F
- }
4 }7 }8 V! F8 R |. ? -
, M/ O: }6 y5 a* V; ~ - //移除所有的本地数据; X. w) @, i8 A
- function _clearAll(){- q1 m; {5 h; G( Q
- result = _getItem({key : _clearAllKey});7 I# i+ ~) Z6 T
- if(result) {
$ D8 {3 x5 V0 N* d$ w5 ` - var allKeys = result.split("|");7 Y/ H+ c, d! l# y( x+ F
- var count = allKeys.length;& |' y; I' W, ^2 d
- for(var i = 0;i < count;i++){( f* Q1 J" k/ T
- if(!!allKeys[i]) {
1 ^6 a8 d. O% p, R! I - _removeItem({key:allKeys[i]});
) t* c5 o! f) J0 q3 {5 Z - }/ O) }* T. N! t9 C
- }" n5 L9 g8 D9 n- p6 y3 a
- }
! ?/ o+ S! u0 O8 D - }0 G2 p- @% v5 K* \
-
( p9 Q/ q! I) F! R, p - ) ~! V9 d0 Y. h0 a) ?7 H% e, K
- /**( v K/ U8 h0 [% @$ r5 V
- * 获取所有的本地存储数据对应的key5 F3 _# c: r1 `4 B, o; x# R, f% [
- * @return {Array} 所有的key+ k8 R; |' k; I( G, h0 N4 P# P# t7 D
- * @private 1 |5 z3 }3 G, ]" p- g. _8 g
- */
- ]2 q1 G$ Y U! s0 k' R - function _getAllKeys(){
* c+ f @( V9 Y - var result = [];2 R% Y7 b) \7 J# |" i8 u* h2 [4 e* k
- var keys = _getItem({key : _clearAllKey});0 ~8 v) e% d, ]2 X! W
- if(keys) {7 m P: I: N5 M3 ^/ G
- keys = keys.split('|');* |+ ^. u: t1 Y1 F- b$ U- l+ I
- for(var i = 0,len = keys.length;i < len;i++){! O7 B7 Z: d& t3 ^ S
- if(!!keys[i]) {0 r9 i0 x* v+ L! J; E. b
- result.push(keys[i]);( u7 t0 c. ]3 x$ A
- }
' O8 p# G A( S! w* B) s7 n - }2 N! Q2 H/ W: R% h; C1 I E
- }
. n1 T( g. H+ ^ - return result ;4 j5 n e9 ]2 u* e3 e7 R
- }: ^2 ?% ~, s/ x/ G0 e2 w2 }' B
- / e, k) e6 U3 m l t7 k
- /**/ K- K9 k3 t& Y3 I9 {& T& }+ l- ]3 C
- * 判断当前浏览器是否支持本地存储:window.localStorage/ g0 j8 x4 z9 c
- * @return {Boolean} true:支持;false:不支持% f& q" C) m7 n1 a; i+ x* e: n/ h
- * @remark 支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+. ^$ O7 v- ?; k, x
- * @private8 Z4 g" N/ x" w( j- E; f
- */2 Z( q3 P% V; p1 j2 w
- var _isSupportLocalStorage = (('localStorage' in window) && (window['localStorage'] !== null)),, T1 x7 [; j5 w
- _isSupportUserData = !!jQuery.browser.ie;8 @) Z( l. m2 ]3 |
-
9 m" m1 n5 D- M1 L4 T; ~, L, e& w - qext.LocalStorage = {3 ^) f3 J4 w& W8 [$ `
- /**
( \- D/ N1 g: r0 ^, ]. ]5 A# G - * 如果支持本地存储,返回true;否则返回false
! X. Y; V5 j" w, p9 R) } - * @type Boolean$ B+ [, a# a! V
- */) f3 j& P& E4 u( h
- isAvailable : _isSupportLocalStorage || _isSupportUserData,
7 }# u* d3 c4 d' I - 4 P; n# b$ @4 L: z0 q t, c
- /**
' A" D, o9 ^9 |5 \+ R2 g9 J P - * 将数据进行本地存储(只能存储字符串信息)5 O1 B$ Q* C4 i T! [9 g: N
- * <pre><code>
p& }% ^9 o4 u - * //保存单个对象! b# f( \( j. M. Z! {+ {
- * qext.LocalStorage.set({
" ^- k B T5 F" K: m! t! |* _ - * key : "username",
7 M: ~; y5 j! x7 [2 `" V& a5 V - * value : "baiduie",
7 T+ y k# A4 R4 p, S- ?1 Z' l9 h: t - * expires : 3600 * 1000+ d- B @6 p7 }$ J# k
- * });2 L3 D. y% b5 T* l! D
- * //保存对个对象
6 G0 D5 N1 R' p8 ?3 |1 N& ` - * qext.LocalStorage.set([{) f; [2 z# [0 h, r& S$ `, a) W
- * key : "username",! X9 e @# G. o0 \# W. O
- * value : "baiduie",# @2 B! E+ W* r7 e9 u
- * expires : 3600 * 1000; D, F9 ]4 d$ h" }+ B
- * },{
4 [4 G; g* h5 Z- X) h; V - * key : "password",$ s- A8 Z) o) r) n! p$ G2 B1 {+ u M
- * value : "zxlie",
; n/ X1 y, {, m/ ] - * expires : 3600 * 1000! e! L+ B( d- g8 V9 u
- * }]);
, z& o/ Y0 t0 d8 Z$ J3 k3 w - * </code></pre>1 R/ D$ d+ P2 q) {% a
- * @param {Object} obj 待存储数据相关配置,可以是单个JSON对象,也可以是由多个JSON对象组成的数组/ B3 M& _+ ?; O( j4 n- j q4 C
- * <ul>- K' c( G1 N' ~
- * <li><b>key</b> : String <div class="sub-desc">待存储数据的key,务必将key值起的复杂一些,如:baidu.username</div></li>: t, z! b; M5 s z- L
- * <li><b>value</b> : String <div class="sub-desc">待存储数据的内容</div></li>9 J8 m2 \' W! C& [
- * <li><b>expires</b> : String/Object (Optional)<div class="sub-desc">数据的过期时间,可以是数字,单位是毫秒;也可以是日期对象,表示过期时间</div></li>- B8 [! H/ F: ]! N R; {- J# W
- * </ul>2 f2 ^# r9 g3 G+ U3 L& ^
- */& b* y8 c8 ^5 i3 q% _& d$ x) K
- set : function(obj){4 V# p5 X8 U4 y2 O/ ~2 Y4 A0 ?
- //保存单个对象
3 U# n7 d1 u* `) _2 k9 a - var _set_ = function(config){ _4 K, I4 O$ A" b/ \* l
- //key校验6 l/ J9 A( U0 u* H4 a5 K) _0 u$ v
- if(!_isValidKey(config.key)) {return;}
! @: f5 A) F# m8 z8 G4 m* C. J7 L
" p" h3 D8 W# r: F- //待存储的数据
3 v7 ?0 G# [) i( n- } - var storageInfo = config || {};
4 w+ t' S8 J6 G" e+ x - 7 t5 Q+ n7 E6 \2 ]+ l: \
- //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
) ?+ J: T" j) L1 k) _& ^6 P1 q1 I - if(_isSupportLocalStorage) {1 ?7 P: r. n6 h* s# M! k T. E. _
- window.localStorage.setItem(storageInfo.key,storageInfo.value);
! V: k. q d$ k* U& U- q5 C, p: ^ - if(config.expires) {9 @/ E5 s# H! N# [! }0 a" k6 l
- var expires;
5 C5 c2 F9 B' g+ F$ s! u& ]5 s% W - //如果设置项里的expires为数字,则表示数据的能存活的毫秒数
# u$ l! ?' J u1 Q - if ('number' == typeof storageInfo.expires) {7 y6 N0 Q0 n3 z1 M( I3 j6 _/ ~
- expires = new Date();
- h. L$ P/ p' K4 \3 Q v - expires.setTime(expires.getTime() + storageInfo.expires);
8 F: ~# T/ w& n; _+ Z/ j - }
5 @# u5 E% G1 p% j! n - ) S# m. h. F; \# V! C1 B* o" n" v
- window.localStorage.setItem(storageInfo.key + ".expires",expires);
2 }. [: ^- _& X% D! ? - }
& N+ }2 r, E/ I: v - } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式
- g* @$ g! U+ r9 F" ~9 l8 v - _setItem(config.key,storageInfo);1 D+ w$ C) q9 @4 }
- }
/ e# X( {1 _6 W! H& |. r - };6 {- R. R) L) h* `# f
- U6 \' { y9 @/ |2 G# m- //判断传入的参数是否为数组 s! l, ~0 d' W) b7 F
- if(obj && obj.constructor === Array && obj instanceof Array){, x, d8 G& H( ~$ r
- for(var i = 0,len = obj.length;i < len;i++){
+ b7 |/ V8 Q) z+ i0 c' W+ p- n/ q - _set_(obj[i]);4 B% x5 G2 o% `6 q; \
- }/ q! d: m9 _# G2 ~' k+ x) V" N) z
- }else if(obj){; ^8 K: f) H) K3 ]& C* A
- _set_(obj);# \& H* C: ?5 w6 G* {
- }* Q( x. }* D# Y8 c Z) r6 l
- },
% u' E* \8 `+ ] r/ k6 V8 J! ` -
0 h1 P7 F8 I4 ~: s) Z! x+ W - /**7 S n F5 B* t. G
- * 提取本地存储的数据
% R3 L7 \' B# m# [) l7 O8 C - * <pre><code>8 C0 T: K! E' a2 u P; \9 i
- * //获取某一个本地存储,返回值为:{key:"",value:"",expires:""},未取到值时返回值为:null1 w' K4 E/ W2 R
- * var rst = qext.LocalStorage.get({
$ M; ^ Q4 y: \( {- j9 X - * key : "username"1 f8 p" w, M# L& Q$ V. a/ j/ |
- * });! c* P3 a0 w5 R4 K T$ W _% z
- * //获取多个本地存储,返回值为:["","",""],未取到值时返回值为:[null,null,null]7 k$ ^9 W9 ]" r1 m: p! R! g
- * qext.LocalStorage.get([{
" u+ {, d% n. X0 @1 `4 m - * key : "username"
* s% o# b. s8 W9 y$ b# k: ~ - * },{
! d& J) q# S% Y - * key : "password"% |$ ~( I- k- |- f/ R
- * },{
! y" |. K$ E- _$ b# k, R" u - * key : "sex"- m1 u( F+ O5 d
- * }]);
5 w- z/ i7 g6 u - * </code></pre>
, N* g; g2 j2 J- u* b, r- S2 \0 Z - * @param {String} obj 待获取的存储数据相关配置,支持单个对象传入,同样也支持多个对象封装的数组格式$ q3 e7 u! b3 b7 _/ V
- * @config {String} key 待存储数据的key) G6 a `+ C; R8 B, ^ }, k4 a: R
- * @return {String} 本地存储的数据,传入为单个对象时,返回单个对象,获取不到时返回null;传入为数组时,返回为数组' h# P1 y* y$ K' P' s2 x/ N
- */
8 Z: _+ u. B# L- G! K; A - get : function(obj){( u0 W! N. V: X
- //获取某一个本地存储
2 J( |5 y/ }2 v4 I g - var _get_ = function(config){
3 c( ^6 |" _( D - //结果 + G& h4 x6 I3 v4 d6 f3 [. x% `
- var result = null;
/ E" M* E. F+ }7 ]0 M/ u5 L - if(typeof config === "string") config = {key : config};
' t5 G# v. @/ z9 n3 w - //key校验% `8 J' p: x7 Q r6 a
- if(!_isValidKey(config.key)) {return result;}$ T7 V t5 v. f; N* ^' g$ m
- 3 e$ s2 m/ e0 X
- //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
; j) I/ ~8 i% \' ^8 l; U) h - if(_isSupportLocalStorage) {
6 Q8 t7 I- K) U - result = window.localStorage.getItem(config.key);) h4 l1 h0 {: J" P. }
- //过期时间判断,如果过期了,则移除该项
g; s# s: Q/ o' I8 N5 _. ~3 S - if(result) {
% O4 B5 c6 c' s0 w+ I- ^ - var expires = window.localStorage.getItem(config.key + ".expires"); J8 U3 A: {7 z% ]! u7 }
- result = {# x# q% |1 m; A9 z: F+ h
- value : result,
- }" U1 N7 T# x - expires : expires ? new Date(expires) : null
! \9 P- o6 x6 l' P+ [# W3 T - };* ], O ~/ K6 h% ^
- if(result && result.expires && result.expires < new Date()) {
' c# i9 U7 P# N3 S# U; N: W8 J9 |5 b - result = null;1 h9 j( D$ U$ y% K! X9 i) Z% c
- window.localStorage.removeItem(config.key);
3 \, L' N+ e7 O" h# e - window.localStorage.removeItem(config.key + ".expires");% H* A3 r4 J( o2 B" E; I: C
- }
; [& F5 q' V( T* @! u# x9 h - }
- c* q* {: w$ v - } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式$ O+ Q C( _1 g4 | S3 q
- //这里不用单独判断其expires,因为UserData本身具有这个判断8 Y9 [: Y, x3 }9 @5 V5 k
- result = _getItem(config);5 p) |, k" V0 Q
- if(result) {
" @9 Y0 |. J* A- J! A8 {: c" _- r s - result = { value : result };8 `( b' H8 C2 i2 d% C# N$ G
- }
9 J2 F) `- ]2 M+ @9 b8 \( n - }
. ? M, H6 ~1 g& q -
& {9 x# W- B+ N: V5 z - return result ? result.value : null;% k) j1 i+ k/ h+ b) l
- }; p0 U) r _- Q7 {; W* s3 E2 ^: |
- 5 f8 b& a/ z* c `+ ]* w9 T
- var rst = null;
* R C2 o0 k8 L) \5 D - //判断传入的参数是否为数组( j! F# X" n1 w- I
- if(obj && obj.constructor === Array && obj instanceof Array){5 Z2 V5 Y6 R& E# z
- rst = [];* x4 |- S( S2 q4 k; s9 N5 H# [
- for(var i = 0,len = obj.length;i < len;i++){- n4 A6 C! w: r% I! X+ s
- rst.push(_get_(obj[i]));
( X$ E" w0 Y4 Q# U4 l. l8 X$ y; u$ } - }5 R4 @. q; B) U; P( ?/ ~7 I
- }else if(obj){+ X& ^ P8 e1 Z5 @( }
- rst = _get_(obj);
$ V' y! |! n0 h1 p - }
; N+ v+ E/ O7 y- Y( W - return rst; R! `0 [5 R, q
- },5 r1 j- X( f/ D8 E. u1 d+ H
-
+ ?( ~; o: `" X2 ~! c' J7 O - /**% _) ~' t c# e+ x) U5 T: t
- * 移除某一项本地存储的数据& W4 L+ g2 S& R; B: d/ t
- * <pre><code>
( |+ k. }+ q/ t- C4 r# b; J - * //删除一个本地存储项3 r" u+ d1 R/ ]: X& [# |
- * qext.LocalStorage.remove({
. ?9 V+ k D. c - * key : "username"' f* @0 `! n5 P# l, g8 `
- * });
( r- a5 K% ?& W+ ~+ m- Q" X - * //删除多个本地存储项目 *
# L, Y0 O4 a8 r% ]/ Q/ `$ f - * qext.LocalStorage.remove([{5 V+ y7 a" u x) G Y- A) y/ |1 w
- * key : "username"
# L6 { q8 m. O - * },{
0 ?9 p1 |7 L/ K+ f' y - * key : "password"' B3 D- J8 q ^- K7 }
- * },{
- w1 B5 Q. s5 @ - * key : "sex" P8 k! P; i0 n. M. k3 N
- * }]);
9 h ^" p$ U- \; n- O( A8 @ - * </code></pre>7 W2 h1 r9 B- q% g
- * @param {String} obj 待移除的存储数据相关配置,支持移除某一个本地存储,也支持数组形式的批量移除
/ t- ^( r2 ?3 Q2 S& T; S- c - * @config {String} key 待移除数据的key/ A4 Z1 h' U! ]) C
- * @return 无
# l. _7 w9 }+ m. h - */* ]2 W6 q. j, R c8 T
- remove : function(obj){
i- y5 q, i2 C+ g- J# g6 l - //移除某一项本地存储的数据
8 r/ }8 I7 @1 ]* _( }; {5 I& z - var _remove_ = function(config){
Y' |/ k0 f! w) O - //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+3 q1 S: L+ u6 I9 p! r
- if(_isSupportLocalStorage) {2 h# r6 Y# T6 `2 c, n
- window.localStorage.removeItem(config.key);, k. B# r. f, K& C7 p$ C! R1 ?
- window.localStorage.removeItem(config.key + ".expires");
+ h5 m0 q/ C; b) g3 i! f, W - } else if(_isSupportUserData){ //IE7及以下版本,采用UserData方式
& l9 J4 ^+ G w1 E* L# l4 m - _removeItem(config);; L9 f# p7 D' r/ B, n7 m1 q
- }0 f& j- J7 q! U9 G
- };
! \1 M: \9 }( n& B! t. O -
) U9 ?/ y) I) i6 b4 P6 x - //判断传入的参数是否为数组
6 B8 q" O1 u a3 \8 M - if(obj && obj.constructor === Array && obj instanceof Array){
( H- P1 s+ s! G - for(var i = 0,len = obj.length;i < len;i++){0 q8 m' o- \5 C5 Y% l& |( W
- _remove_(obj[i]);+ t& e# j4 h2 ]. h9 f) B
- }, ?7 y( L2 k4 D/ P3 I- [' E! f9 v0 m
- }else if(obj){
. x1 h: x4 q) g - _remove_(obj);) O# t# @7 r9 E$ C: K7 i
- }
$ r. W6 _% b) T [8 N! k0 j - },
" v" \! u J( }) Q/ C - 4 _( x, Y8 @0 x- a$ U* W, r( L6 C
- /**; U( {+ L) N8 \& j6 Z( L
- * 清除所有本地存储的数据/ W9 V" @9 k [
- * <pre><code>
1 N r" q# a# ^ ?7 g. w L - * qext.LocalStorage.clearAll();
7 S# @5 R5 V' ^* }7 l, d# i, @6 v, h - * </code></pre>
& d4 F. Q+ \. ]4 E: v: P - */
+ Q( @% X" V) \6 g4 }0 L - clearAll : function(){
4 E* H9 R& w9 F8 Y - //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
. }( ?, }. q! J% q - if(_isSupportLocalStorage) {1 ]# C0 a! C* g3 h, g0 x- V7 A
- window.localStorage.clear();4 u% g; y+ U6 e1 I. h1 G' ^
- } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式
( {; w7 u( W0 u% Q+ \ - _clearAll();3 Q1 X! _0 W8 R
- }
$ s5 H* m! q6 k# h8 H+ `& B - },
' q4 U2 M& r9 J5 z -
) K: O) F# l1 c! t) R9 i# V - //保存单个对象到本地8 X4 H8 }, G$ y/ |" ]6 d0 X- B8 g) K
- save:function(StudentID,ExamID,QuestionID,ExamAnswer){' D9 ]7 V: R9 l, [/ i+ s
- qext.LocalStorage.set({, }# e- _: ?1 }/ U/ O$ `/ o; g
- key : StudentID+ExamID+QuestionID,
5 W! q% R$ x0 X0 F$ y, i - value : "{ StudentID’: ‘"+StudentID+"’, ‘ExamID’: ‘"+ExamID+"’, ‘QuestionID’: ‘"+QuestionID+"’,‘ExamAnswer’: ‘"+ExamAnswer+"’}",% H8 v* C; O$ Q% A/ q' | G' m: Y8 p
- expires : 3600 * 1000 /*单位:ms*/7 Q' l- t) \4 Z- X
- });
! L1 r/ ^$ I! Z* E& ~* | - },6 w4 C* A, C D- R0 C
- /**
" I* ~6 W/ P. ]& N8 x) A% a - * 获取所有的本地存储数据对应的key' |' i+ p1 ~/ A6 e
- * <pre><code>
9 n0 V7 m t4 [+ `* f - * var keys = qext.LocalStorage.getAllKeys();
! o6 `, f8 h& n' E/ J5 [ - * </code></pre>
; L" R8 O( ?' l, @# Z+ k - * @return {Array} 所有的key
2 a" p9 j0 y' M* R* p - */# N, j- @; u9 X
- getAllKeys : function(){
& B* K% S7 f+ C7 a1 x - var result = [];
! p) o: g: h1 ]4 \0 f - //支持本地存储的浏览器:IE8+、Firefox3.0+、Opera10.5+、Chrome4.0+、Safari4.0+、iPhone2.0+、Andrioid2.0+
# i: J) K- W. G - if(_isSupportLocalStorage) {; {; @& G4 @8 s
- var key;# s, r! T- a0 G8 j
- for(var i = 0,len = window.localStorage.length;i < len;i++){" I# @ ^/ n5 G' k5 t6 _% p
- key = window.localStorage.key(i);
. q6 i. b% f' E Y" M - if(!/.+\.expires$/.test(key)) {8 t# @+ h5 y0 W' l5 ^+ @2 @
- result.push(key);: s, b0 Q- ?. E% G
- }9 F V. s% M7 a; t- v& M6 ?
- }
0 `# u5 X1 o8 H/ B2 B# C7 m7 m" \8 ?! A - } else if(_isSupportUserData) { //IE7及以下版本,采用UserData方式6 R2 S r" W+ e3 Z( d. ?0 @" ~
- result = _getAllKeys();4 M& N; A( @' `' T; n; L; t }
- }- c& l+ S. M+ T0 K. m& K3 z
- 2 l; ]1 [, k7 _+ ^" b0 f2 U+ F
- return result;6 w1 T& u+ y" q9 r! c' s
- }
1 v f2 d8 |3 G6 ^$ V2 K- e% t. Q3 V( o - };: y7 p/ S# G6 y8 i+ K; E' f
; S1 t3 w) v% `) ~- })();
5 m1 ~, `/ S. E
复制代码
7 b* g# p% ?( j' r4 V3 n0 s! ]5 j演示地址:http://www.52itstyle.top/localstorage/index.html4 W: o% B2 ] o2 v
4 X) ]! W, ~' |7 ]/ c$ o
HTML5 storage.zip
(46.03 KB, 下载次数: 0, 售价: 2 IT币)
! ?2 R( z: r# k0 w6 z# Q* i" e
; ]5 U; R( X8 i( [& \2 U3 F% V( @: x1 P$ z& w
$ v$ k' C( l6 a9 N7 i0 L h: |: i
7 |8 K; ?/ K' \3 j% e$ N# t) j W8 q- j. l9 N0 k; ?* m' J
|
|