我想在MooTools中实现插件串行下载图片。假设有一个带有图像处理器的div内的img标签的图片。在加载下一个图像之后需要一致地下载每个图像,依此类推,直到所有图像都没有加载。
window.addEvent('domready', function(){
// get all images in div with class 'imageswrapper'
var imagesArray = $$('.imageswrapper img');
var tempProperty = '';
// hide them and set them to the attribute 'data-src' to cancel the background download
for (var i=0; i<imagesArray.length; i++) {
tempProperty = imagesArray[i].getProperty('src');
imagesArray[i].removeProperty('src');
imagesArray[i].setProperty('data-src', tempProperty);
}
tempProperty = '';
var iterator = 0;
// select the block in which we will inject Pictures
var injDiv = $$('div.imageswrapper');
// recursive function that executes itself after a new image is loaded
function imgBomber() {
// exit conditions of the recursion
if (iterator > (imagesArray.length-1)) {
return false;
}
tempProperty = imagesArray[iterator].getProperty('data-src');
imagesArray[iterator].removeProperty('data-src');
imagesArray[iterator].setProperty('src', tempProperty);
imagesArray[iterator].addEvent('load', function() {
imagesArray[iterator].inject(injDiv);
iterator++;
imgBomber();
});
} ;
imgBomber();
});
答案 0 :(得分:3)
我可以在这里看到几个问题。你还没有真正说过这个问题是什么......在你发布它的实际问题(或者用jsfiddle)之前,这更像是一个代码审查/想法
您在domready
中运行此代码,其中浏览器可能已根据src属性启动了图像下载。在开始之前,您最好直接从服务器发送data-src
可能是最大的问题:var injDiv = $$('div.imageswrapper');
会返回一个收集 - 所以[<div.imageswrapper></div>, ..]
- 由于目标可能是多个而无法取inject
dom节点。请改用var injDiv = document.getElement('div.imageswrapper');
。
load
事件存在问题,跨浏览器存在.addEvent('load')
。它们需要在执行后清理,如IE&lt;例如,每当动画gif循环时,它将触发load
。此外,您没有onerror
和onabort
处理程序,这意味着您的加载程序将停止在404或任何其他意外响应。
您不应该使用data-src
来存储数据,这很慢。 MooTools具有元素存储 - 使用el.store('src', oldSource)
和el.retrieve('src')
以及el.eliminate('src')
。快多了。
将迭代器暴露给上层作用域。
使用mootools api - 使用.set()
和.get()
而非.getProperty()
和.setProperty()
for (var i)
迭代器不适合用于异步操作。应用程序的控制流将继续运行,不同的操作可能会引用错误的迭代器索引。看看你的代码,情况并非如此,但你应该使用来自.each(fn(item, index), scope)
/ Elements
方法的mootools Array
。
无论如何,你的问题已经在几个层面上解决了。
例如,我写了pre-loader - 一个框架无关的图像加载器插件,可以在 parallel 或 pipelined 中下载图像数组(就像你正在尝试to)onProgress
等事件 - 请参阅http://jsfiddle.net/dimitar/mFQm6/ - 请参阅readme.md底部的屏幕截图:
MooTools也通过Asset.js - http://mootools.net/docs/more/Utilities/Assets#Asset:Asset-image和Asset.images解决了这个问题(无需等待上一张图片)。看到灵感来源 - https://github.com/mootools/mootools-more/blob/master/Source/Utilities/Assets.js
以下是通过我的预加载器类执行此操作的示例:http://jsfiddle.net/dimitar/JhpsH/
(function(){
var imagesToLoad = [],
imgDiv = document.getElement('div.injecthere');
$$('.imageswrapper img').each(function(el){
imagesToLoad.push(el.get('src'));
el.erase('src');
});
new preLoader(imagesToLoad, {
pipeline: true, // sequential loading like yours
onProgress: function(img, imageEl, index){
imgDiv.adopt(imageEl);
}
});
}());