├── README.md ├── yStorage.js └── yStorage.pkg.js /README.md: -------------------------------------------------------------------------------- 1 | ## yStorage —— 完善的本地存储封装 2 | 3 | 本地存储组件,封装`localStorage`和`sessionStorage`,支持缓存,支持数据项存在时长。 4 | 5 | ### API 6 | 7 | #### 主方法 `yStorage` 8 | 9 | ```js 10 | yStorage(key, value, time); 11 | ``` 12 | 13 | * 如果只有 **一个参数** 时,为`get`方法;如果 **多个参数** 时,为`set`方法。 14 | * 第二个参数 `value` 支持任何类型的值。 15 | * `value` 为 `undefined` 或 `null` 为删除操作。 16 | * `time` 为存储时间, 17 | * `-1` 表示仅存在会话里(sessionStorage); 18 | * `0` 或没有此参数,表示永久存储; 19 | * 其他数值,表示存储的时间,超过后,会被删除。 20 | 21 | #### 清除方法 `yStorage.clear` 22 | 23 | ```js 24 | yStorage.clear(); 25 | ``` 26 | 27 | * 清除所有数据 28 | 29 | #### 配置方法 `yStorage.init` 30 | 31 | ```js 32 | yStorage.init(version); 33 | ``` 34 | 35 | * 此方法在于优化相关业务逻辑,如果只做一个库来用,那么可以不关心此方法。 36 | * 参数`version`为当前业务前端代码版本号,如果版本号更改了,那么会自动清除所有数据(代码变了,存储的数据的结构可能会影响到代码,代码要做兼容,因此清除数据,避免此麻烦) 37 | * 在`init`过程中,会自动检查是否到该清理数据的时间,如果到了,那么会去清理无效数据。 38 | 39 | ### 相关问题 40 | 41 | * 为了减少调用storage的API次数,组件中包含缓存Cache。 42 | * 取数据,如果Cache内存在,则从Cache里获取。 43 | * 取数据,仅从storage获取数据的第一次,会判断是否超时,之后,从Cache里获取的,不会检查超时。 44 | -------------------------------------------------------------------------------- /yStorage.js: -------------------------------------------------------------------------------- 1 | var BASETAG = '_baseInfo', // 存储 Storage 配置信息 2 | INTERVAL = 7 * 24 * 60 * 60 * 1000; // 7天清理一下 localStorage 3 | 4 | // Empty Function 5 | function EmplyFunc() {} 6 | 7 | // Null Function 8 | function NullFunc() { 9 | return null; 10 | } 11 | 12 | // 空的 Storage,模拟相关接口 13 | var EmplyStorage = { 14 | size: function() { 15 | return 0; 16 | }, 17 | get: NullFunc, 18 | set: EmplyFunc, 19 | remove: EmplyFunc, 20 | clear: EmplyFunc 21 | }; 22 | 23 | // 根据 type 创建 Storage 对象 24 | function createStorage(type) { 25 | var storage = (type in window) && window[type]; 26 | return storage ? { 27 | // 获取 Size 28 | size: function() { 29 | return storage.length; 30 | }, 31 | // 通过 index 获取键值 key 32 | key: (function() { 33 | return storage.key ? function(index) { 34 | return storage.key(index); 35 | } : NullFunc; 36 | })(), 37 | // 通过键值 key 获取数据 38 | get: (function() { 39 | return storage.getItem ? function(key) { 40 | try { 41 | return JSON.parse(storage.getItem(key)); 42 | } catch (e) { 43 | return null; 44 | } 45 | } : NullFunc; 46 | })(), 47 | // 设置键值 key 对应的数据值为 value 48 | set: (function() { 49 | return storage.setItem ? function(key, value) { 50 | try { 51 | return storage.setItem(key, JSON.stringify(value)); 52 | } catch (e) { 53 | return void 0; 54 | } 55 | } : EmplyFunc; 56 | })(), 57 | // 移除键值 key 对应的数据项 58 | remove: (function() { 59 | return storage.removeItem ? function(key) { 60 | return storage.removeItem(key); 61 | } : EmplyFunc; 62 | })(), 63 | // 清除数据 64 | clear: (function() { 65 | return storage.clear ? function() { 66 | return storage.clear(); 67 | } : EmplyFunc; 68 | })() 69 | } : EmplyStorage; 70 | } 71 | 72 | // 获取当前时间 73 | function now() { 74 | return new Date().getTime(); 75 | } 76 | 77 | // Storage 对象 和 本地缓存 78 | var ls = createStorage('localStorage'), 79 | ss = createStorage('sessionStorage'), 80 | useCache = false, 81 | cache = {}; 82 | 83 | // 检查数据是否超时,如果超时,删除数据。 84 | // 同时将可用数据加入本地缓存,方面以后获取 85 | function checkExpires() { 86 | var time = now(), 87 | i, len, key, value; 88 | for (i = 0, len = ls.size(); i < len; i++) { 89 | key = ls.key(i); 90 | value = ls.get(key); 91 | if (value && key !== BASETAG) { 92 | if (value.expires > 0 && value.createTime + value.expires < time) { 93 | ls.remove(key); 94 | } else { 95 | cache[key] = value.data; 96 | } 97 | } 98 | } 99 | } 100 | 101 | // 主方法 102 | var yStorage = function(key, value, time) { 103 | var argsNum = arguments.length, 104 | data = null; 105 | // 一个参数时,是获取数据 106 | if (argsNum === 1) { 107 | // 检查 key 是否在本地缓存里,如果在直接返回 108 | if (useCache && key in cache) { 109 | data = cache[key]; 110 | } else { 111 | data = ss.get(key) || (function() { 112 | var tmp = ls.get(key); 113 | if (tmp) { 114 | // 判断数据是否可用(未超时),如果可用,返回,否则删除 115 | if (tmp.expires === 0 || (tmp.createTime + tmp.expires > now())) { 116 | return tmp.data; 117 | } 118 | ls.remove(key); 119 | } 120 | return null; 121 | })(); 122 | cache[key] = data; 123 | } 124 | return data; 125 | } else if (argsNum > 1) { // 参数大于1,则肯定是变更操作 126 | // value值是 undefined 或者 null,都是删除此键值对 127 | if (value === void 0 || value === null) { 128 | delete cache[key]; 129 | return ss.remove(key) || ls.remove(key); 130 | } else { 131 | // 将值存入缓存 132 | cache[key] = value; 133 | time = time || 0; 134 | // 时间等于 -1, 则存入 SessionStorage 135 | if (time === -1) { 136 | return ss.set(key, value); 137 | } else { 138 | // 存入 localStorage 139 | return ls.set(key, { 140 | data: value, 141 | createTime: now(), 142 | expires: time 143 | }); 144 | } 145 | } 146 | } 147 | }; 148 | 149 | yStorage.setCache = function(bool) { 150 | useCache = !!bool; 151 | }; 152 | 153 | // 清除数据 154 | yStorage.clear = function() { 155 | var info = ls.get(BASETAG); 156 | ss.clear(); 157 | ls.clear(); 158 | ls.set(BASETAG, info); 159 | }; 160 | 161 | // 初始化操作(非必须) 162 | yStorage.init = function(version) { 163 | var info = ls.get(BASETAG) || {}, 164 | culVersion = info.version, 165 | lastCheckTime = info.cTime, 166 | changed = false; 167 | // 判断版本是否相同,如果不同则清空 localStorage 168 | if (!culVersion || culVersion !== version) { 169 | changed = true; 170 | ls.clear(); 171 | culVersion = version; 172 | } 173 | // 检查后一次 cheak 时间,如果超过设置时间,而进行一次 check 174 | if (!lastCheckTime || now() - lastCheckTime > INTERVAL) { 175 | changed = true; 176 | checkExpires(); 177 | lastCheckTime = now(); 178 | } 179 | if (changed) { 180 | ls.set(BASETAG, { 181 | version: culVersion, 182 | cTime: lastCheckTime 183 | }); 184 | } 185 | }; 186 | -------------------------------------------------------------------------------- /yStorage.pkg.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | var BASETAG = '_baseInfo', // 存储 Storage 配置信息 3 | INTERVAL = 7 * 24 * 60 * 60 * 1000; // 7天清理一下 localStorage 4 | 5 | // Empty Function 6 | function EmplyFunc() {} 7 | 8 | // Null Function 9 | function NullFunc() { 10 | return null; 11 | } 12 | 13 | // 空的 Storage,模拟相关接口 14 | var EmplyStorage = { 15 | size: function() { 16 | return 0; 17 | }, 18 | get: NullFunc, 19 | set: EmplyFunc, 20 | remove: EmplyFunc, 21 | clear: EmplyFunc 22 | }; 23 | 24 | // 根据 type 创建 Storage 对象 25 | function createStorage(type) { 26 | var storage = (type in window) && window[type]; 27 | return storage ? { 28 | // 获取 Size 29 | size: function() { 30 | return storage.length; 31 | }, 32 | // 通过 index 获取键值 key 33 | key: (function() { 34 | return storage.key ? function(index) { 35 | return storage.key(index); 36 | } : NullFunc; 37 | })(), 38 | // 通过键值 key 获取数据 39 | get: (function() { 40 | return storage.getItem ? function(key) { 41 | try { 42 | return JSON.parse(storage.getItem(key)); 43 | } catch (e) { 44 | return null; 45 | } 46 | } : NullFunc; 47 | })(), 48 | // 设置键值 key 对应的数据值为 value 49 | set: (function() { 50 | return storage.setItem ? function(key, value) { 51 | try { 52 | return storage.setItem(key, JSON.stringify(value)); 53 | } catch (e) { 54 | return void 0; 55 | } 56 | } : EmplyFunc; 57 | })(), 58 | // 移除键值 key 对应的数据项 59 | remove: (function() { 60 | return storage.removeItem ? function(key) { 61 | return storage.removeItem(key); 62 | } : EmplyFunc; 63 | })(), 64 | // 清除数据 65 | clear: (function() { 66 | return storage.clear ? function() { 67 | return storage.clear(); 68 | } : EmplyFunc; 69 | })() 70 | } : EmplyStorage; 71 | } 72 | 73 | // 获取当前时间 74 | function now() { 75 | return new Date().getTime(); 76 | } 77 | 78 | // Storage 对象 和 本地缓存 79 | var ls = createStorage('localStorage'), 80 | ss = createStorage('sessionStorage'), 81 | useCache = false, 82 | cache = {}; 83 | 84 | // 检查数据是否超时,如果超时,删除数据。 85 | // 同时将可用数据加入本地缓存,方面以后获取 86 | function checkExpires() { 87 | var time = now(), 88 | i, len, key, value; 89 | for (i = 0, len = ls.size(); i < len; i++) { 90 | key = ls.key(i); 91 | value = ls.get(key); 92 | if (value && key !== BASETAG) { 93 | if (value.expires > 0 && value.createTime + value.expires < time) { 94 | ls.remove(key); 95 | } else { 96 | cache[key] = value.data; 97 | } 98 | } 99 | } 100 | } 101 | 102 | // 主方法 103 | var yStorage = function(key, value, time) { 104 | var argsNum = arguments.length, 105 | data = null; 106 | // 一个参数时,是获取数据 107 | if (argsNum === 1) { 108 | // 检查 key 是否在本地缓存里,如果在直接返回 109 | if (useCache && key in cache) { 110 | data = cache[key]; 111 | } else { 112 | data = ss.get(key) || (function() { 113 | var tmp = ls.get(key); 114 | if (tmp) { 115 | // 判断数据是否可用(未超时),如果可用,返回,否则删除 116 | if (tmp.expires === 0 || (tmp.createTime + tmp.expires > now())) { 117 | return tmp.data; 118 | } 119 | ls.remove(key); 120 | } 121 | return null; 122 | })(); 123 | cache[key] = data; 124 | } 125 | return data; 126 | } else if (argsNum > 1) { // 参数大于1,则肯定是变更操作 127 | // value值是 undefined 或者 null,都是删除此键值对 128 | if (value === void 0 || value === null) { 129 | delete cache[key]; 130 | return ss.remove(key) || ls.remove(key); 131 | } else { 132 | // 将值存入缓存 133 | cache[key] = value; 134 | time = time || 0; 135 | // 时间等于 -1, 则存入 SessionStorage 136 | if (time === -1) { 137 | return ss.set(key, value); 138 | } else { 139 | // 存入 localStorage 140 | return ls.set(key, { 141 | data: value, 142 | createTime: now(), 143 | expires: time 144 | }); 145 | } 146 | } 147 | } 148 | }; 149 | 150 | yStorage.setCache = function(bool) { 151 | useCache = !!bool; 152 | }; 153 | 154 | // 清除数据 155 | yStorage.clear = function() { 156 | var info = ls.get(BASETAG); 157 | ss.clear(); 158 | ls.clear(); 159 | ls.set(BASETAG, info); 160 | }; 161 | 162 | // 初始化操作(非必须) 163 | yStorage.init = function(version) { 164 | var info = ls.get(BASETAG) || {}, 165 | culVersion = info.version, 166 | lastCheckTime = info.cTime, 167 | changed = false; 168 | // 判断版本是否相同,如果不同则清空 localStorage 169 | if (!culVersion || culVersion !== version) { 170 | changed = true; 171 | ls.clear(); 172 | culVersion = version; 173 | } 174 | // 检查后一次 cheak 时间,如果超过设置时间,而进行一次 check 175 | if (!lastCheckTime || now() - lastCheckTime > INTERVAL) { 176 | changed = true; 177 | checkExpires(); 178 | lastCheckTime = now(); 179 | } 180 | if (changed) { 181 | ls.set(BASETAG, { 182 | version: culVersion, 183 | cTime: lastCheckTime 184 | }); 185 | } 186 | }; 187 | 188 | 189 | if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { 190 | define(function() { 191 | return yStorage; 192 | }); 193 | } else if (typeof module !== 'undefined' && module.exports) { 194 | module.exports = yStorage; 195 | } else { 196 | window.yStorage = yStorage; 197 | } 198 | 199 | })(); --------------------------------------------------------------------------------