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