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