我的lazyload插件中的bug为mootools

时间:2013-11-01 06:26:39

标签: javascript mootools

我想在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();
});

1 个答案:

答案 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。此外,您没有onerroronabort处理程序,这意味着您的加载程序将停止在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底部的屏幕截图:

pipeline waterfall

parallel waterfall

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);
        }
    });

}());