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