Javascript iPad上JS的图像缓存
我正在开发一个用于iPad的纹理选择器。所以基本上只是一堆图像元素。为了避免图像重新加载和延迟,我缓存并重用JS中的Javascript iPad上JS的图像缓存,javascript,ipad,html,caching,Javascript,Ipad,Html,Caching,我正在开发一个用于iPad的纹理选择器。所以基本上只是一堆图像元素。为了避免图像重新加载和延迟,我缓存并重用JS中的image对象。诸如此类 /** * Asynchronous version of memoize for use with callback functions. Asserts * that last argument is the callback. * * @param {Function} func * @return {Function} */ uti
image
对象。诸如此类
/**
* Asynchronous version of memoize for use with callback functions. Asserts
* that last argument is the callback.
*
* @param {Function} func
* @return {Function}
*/
util.memoize.async = function(func) {
var cache = {};
return function() {
var hash = JSON.stringify(arguments);
var args = Array.prototype.splice.call(arguments, 0);
var callback = args.pop();
if (hash in cache) {
return callback.apply(this, cache[hash]);
}
args.push(function() {
cache[hash] = Array.prototype.splice.call(arguments, 0);
callback.apply(this, cache[hash]);
});
return func.apply(this, args);
};
};
/**
* Creates new Image element and calls back with loaded image.
* @param {string} url
*/
io.GetImage = function(url, callback) {
var img = new Image();
img.onload = function() {
callback(img);
};
img.src = url;
};
picker.image_ = util.memoize.async(io.GetImage);
然后,每当我需要图像时,我调用picker.image\uz
并获取缓存的图像。它在桌面、Chrome、Firefox、Safari上都能完美地工作,但在iPad上,我得到的是空(未加载)图像。为什么呢?我非常喜欢这种方法,它的性能非常好
从DOM中删除图像数据时,MobileSafari似乎会将其删除。可能是这样吗
更新:澄清一下,加载的数据是动态的,因此它不是最适合的用例
更新*:没有完全令人满意的答案,这是我的解决方案。请注意,复制方法非常慢
/**
* Creates new Image element and calls back with loaded image.
* @param {string} url
*/
var GetImage = function(url, callback) {
var img = new Image();
img.onload = function() {
callback(img);
};
img.src = url;
};
/**
* @param {number} num maximum number of stored images
*/
var ImagePool = function(num) {
this.limit_ = num;
this.canvases_ = {};
this.order_ = [];
};
/**
* Retrieve image from cache.
*
* @param {string} url URL of request image
* @param {function(HTMLCanvasElement)} callback
*/
ImagePool.prototype.get = function(url, callback) {
if (this.canvases_[url] !== undefined) {
callback(this.copy_(url));
} else {
if (this.limit_ && this.order_.length == this.limit_) {
delete this.canvases_[url];
this.order_.pop();
}
GetImage(realUrl, function(img) {
var c = document.createElement('canvas');
c.width = img.width;
c.height = img.height;
var ctx = c.getContext('2d');
ctx.drawImage(img, 0, 0);
this.canvases_[url] = c;
this.order_.unshift(url);
callback(this.copy_(url));
}.bind(this));
}
};
/**
* @param {string} url
* @return {HTMLCanvasElement}
* @private
*/
ImagePool.prototype.copy_ = function(url) {
var c = document.createElement('canvas'),
cached = this.canvases_[url];
c.width = cached.width;
c.height = cached.height;
var ctx = c.getContext('2d');
ctx.drawImage(cached, 0, 0);
return c;
};
我认为使用HTML5离线应用程序缓存可以最好地解决您的问题。列出要缓存的资源,用户访问请求这些资源的页面后,这些资源将被缓存以供以后使用。您仍然需要让UI等待图像加载,但一旦图像加载,您就不必担心它们被删除,因为它们不在DOM中(建议也删除DOM中但未显示在屏幕上的图像) 显然,Safari Mobile有一个5MB的缓存限制,可以通过要求用户同意扩展它()来提高这个限制。中的一条评论表明,此扩展提示最快可在iOS 4上使用 有用链接:
- -一些关于在Safari中使用HTML 5脱机应用程序存储的文档
- -这是一篇较老的博文(2009-2010),但作者对使用HTML5功能(标题为“HTML5脱机应用程序缓存”)有一些很好的建议
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
我会使用嵌入式图像srcbase64编码。检查一下 因此,如果需要,可以将数据存储为JSON字符串,并在需要时将其取回。如果从其他URL调用图像,也可以将其保存到localStorage
是的,这会给你带来巨大的html内容和存储空间,但在你的情况下,这绝对值得。那么你为什么不把它保存在DOM中,让它不可见呢?我必须在我的UI系统中竭尽全力做到这一点,这绝对不是一个优雅的解决方案(我正在寻找的)。我确实遇到了移动Safari的局限性,到目前为止,我的解决方法是维护图像池,将每个下载的图像呈现到画布上,并在需要时进行复制。也许我最终会应用应用程序缓存,这些数据是动态的,我必须不断地将更新推送到清单。几乎忘记了@skrat这个问题-您肯定需要编辑您的问题,以添加图像是动态数据的要求。“这改变了很多事情。”斯卡拉——我只是好奇;为什么你的图像会如此动态?这是一个用于画布绘制的纹理库。用户生成了一个。这是尝试过的,但这个问题归结为移动Safari的6MB限制。不管它是否在DOM中。