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