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