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