WebStorageクラスみたいなの作った(多分未完)
web storageなるものがあるんですよ(唐突)
これWeb Storage
要はグローバルオブジェクトが持ってるストレージです(適当)
やばい。フロントの人たちに刺される。
web storageには2種類、sessionStorageとlocalStorageがあります。
sessionStorageはブラウザを閉じるまで、localStorageは永続的に、保存したドメイン上で残り続けます。
web storageはKVSで、僕はてっきりObjectなのかと今日まで思ってたのですが、JSONとまるまる同じみたいです。NumberとかObjectをvalueに突っ込むとtoString()されちゃうので注意です。
ブラウザ対応状況としては、PCはIE8+、SPは大体どれでも大丈夫と、業務でも使えそうなレベルになってきています。で、どうやらcssとかjs等の外部ファイルの中身を突っ込んでおくと捗るとの話を聞き、今日早速クラスを作ってみました。まだ実用には程遠いですが、大体こんな感じになるだろうなー、って感じで。
実装する上で色々決まり事をしました。というかほとんど、教えてくれたTohlSMALLFIELD氏のパクリです。ごめんなさい
名前空間で管理する
逐一KVの組で管理してもいいのですが、値が多くなり過ぎると汚くなりそうなので、名前空間をkeyに、storeする値をvalueに入れることにしました。とは言え、書いた通りJSONみたいな形なので、Objectを入れ子にはできません。そこで
storeするときはJSON.stringify、loadするときはJSON.parseする
これも完全にTohl氏の受け売りなのですが、各名前空間のvalueにはObjectをしまいます。しかしObjectのまましまうとtoStringされておかしくなっちゃうので、JSON.stringifyとJSON.parseでstore、loadを管理します。
localStorageを使用し、expiresを設定できるようにする
これも完全にTo(ry
書いた通り、web storageには2種類あるのですが、ブラウザを閉じると初期化されてしまうsessionStorageを使うよりは、localStorageにexpiresを設定できるようにし、cookieの拡張のように使えるようにすると便利そうです(受け売り。
というわけで、storeするObjectの形は
item[key] = { val: val, expire: Date.now()+expire };
みたいな感じになり、loadするときにDate.now()がitem[key].expireよりも大きかったら、値を返さずitem[key]を削除すれば良いという実装にしました
- private
var LS = win.localStorage; function constructor(){ set({}); } function get(){ return JSON.parse(LS.getItem(ns)); } function set(obj){ LS.setItem(ns,JSON.stringify(obj)); }
getは、名前空間をkeyにしたvalueを取り出してパースして返す
setは、引数のObjectをstringifyしてlocalStrageに名前空間をkeyとしたvalueとしてstoreする
constructorは、空のObjectをsetする
- public
function save(key,val,expire,force){ var item = get(), f = force ? force : false; if(item[key]&&!force){return false;} item[key] = { val: val, expire: expire ? Date.now()+expire : 0 }; set(item); return true; } function load(key){ var item = get(); if(item[key]&&(!item[key].expire||item[key].expire>Date.now())){ return item[key].val; }else{ remove(key); return false; } } function remove(key){ var item = get(); if(item[key]){ delete item[key]; set(); return true; }else{return false;} } function clear(){ LS.clear(); }
save、ちょっと引数多くなってしまった。仕方ないかな
saveはkeyとvalueでlocalStorageにsetItemする。expireは任意で、単位はmsec。Date.now()に加算して保存する。forceはbooleanで、仮に既にkeyが存在していても、forceがtrueだったら上書きする。
loadは引数のkeyをstorageから探し、expireが指定されてない若しくは期限内である場合にvalueを返す。そうでなければ後述のremoveを呼び出し、storage内から値を削除する
removeはkeyを引数に、key-valueの組みが存在すればそれを削除してsetし直す。
clearはweb storageのメソッドをそのまま使い、storage全体をクリアする。
以上です。あーまた長くなってしまった。どうしたらもうちょい読みやすくできるんでしょ。
で、このクラス数十分で書いたので穴だらけだろうし、そもそも当初の目的である外部ファイルのキャッシュみたいな目的を達成するようには書かれていないので改良が当然必要です。
フロントエンドエンジニアの皆様、この穴だらけのゴミクラスを殴って蹴ってくださいお願いしますうううううううううううううう
ではまた