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