相信每一個開發者都知道緩存的重要性。從頭至尾有緩存的后臺(memcached,xcache等。) 來減輕db的壓力。對內容分發網絡(CDN)緩存中希望你的瀏覽器緩存那些不止一次的加載資源。當然, 有客戶端緩存,所以你不要重復昂貴的操作(即使是算法或大量的運算)。
這是介紹的是一個不錯的javascript的方面的客戶端解決方案,可選配支持HTML5本地存儲器.
function CacheProvider() { // values will be stored here this._cache = {}; }
try { CacheProvider.hasLocalStorage = ('localStorage' in window) && window['localStorage'] !== null; } catch (ex) { CacheProvider.hasLocalStorage = false;
}
這里使用try catch的主要原因是 盡管firefox支持該屬性,但是需要在about:config中設置并開啟,否則將會報錯。所以一個簡單的if else不能滿足需求。
下面我們將增加對象本地存儲機制的支持。這個技術是借鑒了
Christopher Blizzard的一篇不錯的文章 Saving data with local storage – for which those who didn’t know, you can only store string
’s into local storage. Thus we have this…
if (CacheProvider.hasLocalStorage) { Storage.prototype.setObject = function(key, value) { this.setItem(key, JSON.stringify(value)); }; Storage.prototype.getObject = function(key) { return JSON.parse(this.getItem(key)); }; }
現在就到了我們的三個核心方法了,分別是 get, set, 和clear.
CacheProvider.prototype = { /** * {String} k - the key * {Boolean} local - get this from local storage? * {Boolean} o - is the value you put in local storage an object? */ get: function(k, local, o) { if (local && CacheProvider.hasLocalStorage) { var action = o ? 'getObject' : 'getItem'; return localStorage[action](k) || undefined; } else { return this._cache[k] || undefined; } }, /** * {String} k - the key * {Object} v - any kind of value you want to store * however only objects and strings are allowed in local storage * {Boolean} local - put this in local storage */ set: function(k, v, local) { if (local && CacheProvider.hasLocalStorage) { if (typeof v !== 'string')) { // make assumption if it's not a string, then we're storing an object localStorage.setObject(k, v); } else { try { localStorage.setItem(k, v); } catch (ex) { if (ex.name == 'QUOTA_EXCEEDED_ERR') { // developer needs to figure out what to start invalidating throw new Exception(v); return; } } } } else { // put in our local object this._cache[k] = v; } // return our newly cached item return v; }, /** * {String} k - the key * {Boolean} local - put this in local storage * {Boolean} o - is this an object you want to put in local storage? */ clear: function(k, local, o) { if (local && CacheProvider.hasLocalStorage) { localStorage.removeItem(k); } // delete in both caches - doesn't hurt. delete this._cache[k]; } };
注意在這篇文章的開始,就說了Cache Provider 是可選支配的本地存儲,首先然讓我們看一個沒有本地存儲的例子:
var cache = new CacheProvider; window.getElementsByClassName = getElementsByClassName || function(c) { var reg = cache.get(c) || cache.set(c, new RegExp("(?:^|s+)" + c + "(?:s+|$)")); var elements = document.getElementsByTagName('*'); var results = []; for (var i = 0; i < elements.length; i++) { if (elements[i].className.match(reg)) { results.push(elements[i]); } } return results;
};
備注:下次你調用類函數的時候, 將會用預先編譯好的正則表達式替代夠建造一個表達式。
再舉一個例子:比如 對于大的應用程序需要i18n,你可以緩存一個編譯好的html字符串進入本地存儲中。
var i18nCache = new CacheProvider; if (i18nCache.get('topnav')) { $('#nav').html(i18nCache.get('topnav')); } else { ajax('top-nav.tmpl', function(html) { i18nCache.set('topnav', html); $('#nav').html(i18nCache.get('topnav')); }); }
除此之外,你開可以做很多外部資源緩存到本地的事情,加油:)
上一篇 Access數據庫技術(63)