我有一个充满javascript的网页,以及一些资源,如javascript的图像资源。我使用websocket与服务器通信; javascript解析套接字的数据并相应地处理页面呈现。一切正常,除非它没有。
问题似乎是该页面包含我想在javascript控制下显示部分内容的图像。无论我如何玩延迟,显然有些情况下,在javascript尝试使用它们之前,图像似乎没有完全下载。结果是在呈现页面时图像丢失,在一小部分时间内都会丢失。
我不习惯那些你没有严格控制什么时候会发生什么的语言和协议,所以服务器和浏览器运送东西并以不受控制和异步的顺序执行东西会让我烦恼。因此,我想停止依赖显然不可靠的技巧,比如推迟。我想要做的只是下载整个页面,然后打开我的websocket并将我的图像和其他资源发送到通过它。当该过程完成后,我知道从websocket接受其他命令并继续执行页面操作是安全的。换句话说,我想颠覆浏览器异步处理资源,并在javascript控制下连续处理它。
从服务器向下插入图像文件很容易,我可以毫不费力地制定协议。将数据捕获为字节数组也很容易。
但是如何将它们解释为图像?
我知道这种方法存在缺点。我不会对我的图片进行浏览器缓存,并且初始页面无法快速加载。我没关系。我只是厌倦了95%的工作解决方案,不得不想知道我所做的每件浏览器是否适用。 (从IE 8到明年的所有工作都是Chrome的要求。)
这种方法可行吗?是否有更好的方法来获得严格的,可移植的资源加载控制?
答案 0 :(得分:0)
除了图像之外,您还没有特别关注等待的资源,但如果它们都是图像,那么您可以使用此loadMonitor
对象来监控N个图像何时完成加载:< / p>
function loadMonitor(/* img1, img2, img3 */) {
var cntr = 0, doneFn, self = this;
function checkDone() {
if (cntr === 0 && doneFn) {
// clear out doneFn so nothing that is done in the doneFn callback
// accidentally cause the callback to get called again
var f = doneFn;
doneFn = null;
f.call(self);
}
}
function handleEvents(obj, eventList) {
var events = eventList.split(" "), i;
function handler() {
--cntr;
for (i = 0; i < events.length; i++) {
obj.removeEventListener(events[i], handler);
}
checkDone();
}
for (i = 0; i < events.length; i++) {
obj.addEventListener(events[i], handler);
}
}
this.add = function(/* img1, img2, img3 */) {
if (doneFn) {
throw new Error("Can't call loadMonitor.add() after calling loadMonitor.start(fn)");
}
var img;
for (var i = 0; i < arguments.length; i++) {
img = arguments[i];
if (!img.src || !img.complete) {
++cntr;
handleEvents(img, "load error abort");
}
}
};
this.start = function(fn) {
if (!fn) {
throw new Error("must pass completion function as loadMonitor.start(fn)");
}
doneFn = fn;
checkDone();
};
// process constructor arguments
this.add.apply(this, arguments);
}
// example usage code
var cardsImage = new Image();
cardsImage.src = ...
var playerImage = new Image();
playerImage.src = ...
var tableImage = new Image();
var watcher = new loadMonitor(cardsImage, playerImage, tableImage);
// .start() tells the monitor that all images are now in the monitor
// and passes it our callback so it can now tell us when things are done
watcher.start(function() {
// put code here that wants to run when all the images are loaded
});
// the .src value can be set before or after the image has been
// added to the loadMonitor
tableImage.src = ...
注意,您必须确保放在loadMonitor中的所有图像都得到.src
分配,否则loadMonitor永远不会调用它的回调,因为该图像永远不会完成。