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