在javascript(React,Jquery)应用上预加载图片,加载两次图片

时间:2016-11-08 12:40:45

标签: javascript image dom browser-cache preload

  • 请查看下面的编辑3,因为我发现它不是React的问题,而是浏览器的chaching机制。

我正在尝试创建一个应用程序,用给定的图像数组url创建一些简单的轮播。我编写了一个模块,可以帮助我在加载所有图像后调用回调,这就是它的外观:

ImagesLoader.js

export default {
    // a module that loads an array of images urls and when completes
    // calls a callback with the images elements array

    load(imagesUrlsArray, callback){
        const imagesLoaded = [];
        imagesUrlsArray.map((url) => {
            const img = new Image();
            img.onload = () => {
                imagesLoaded.push(img);
                if(imagesUrlsArray.length === imagesLoaded.length){
                    callback(imagesLoaded);
                }
            };
            img.src = url;
        });
    }
}

我知道我可以使用promises并在加载所有网址后解决,而且现在不会检查错误。

这是我的组件使用从上面的模块中恢复的图像更新状态的地方:

componentDidMount() {
    ImagesLoader.load(this.props.images, (loadedImages) => {
        const imagesStateData = this.calculateImagesStateData(loadedImages);
        this.setState(Object.assign({},
            imagesStateData,
            {
                loaded: true,
                loadedImages: loadedImages
            }
        ));
    });
}

当我每次再次加载图片时点击下一个或上一个按钮(查看下面的屏幕截图)时会发生什么,我无法理解为什么。

这是我第一次用reactjs做这件事,jquery没有问题

Network tab on chrome

以下是我传递图片网址的方式:

export default class App extends Component {
  render() {

    var images = [
      "http://www.wallpapereast.com/static/images/excellent-love-quotes-wallpaper-hd.jpg",
      "http://www.wallpapereast.com/static/images/My-Samsung-Galaxy-S3-Wallpaper-HD-Landscapes1.jpg",
      "https://s-media-cache-ak0.pinimg.com/236x/58/01/02/5801020fea36221ffba33633f99a7d81.jpg",
      "http://www.wallpapereast.com/static/images/pier_1080.jpg",
      "http://www.wallpapereast.com/static/images/wallpaper-black-hd-hd-wallpapers.jpg",
      "http://1.bp.blogspot.com/-dvg12YJKaKg/UnVfkMke7jI/AAAAAAAAUaU/O86x5FMgEuk/s1600/longcat.gif"
    ];

    var settings = {
      autoPlay: true,
      arrows: true
    };

    return (
      <Layout>
        <ReactCarousel images={images} width={500} height={300} settings={settings}/>
      </Layout>
    );
  }
}

编辑: 设法举一个简短的例子。 http://codepen.io/anon/pen/ObyRPX,我在构建此示例时可以看到的是,如果我不使用ImageItem组件并渲染一个简单的<img src='image.src'/>元素,那么它的效果很好,所以我想我的问题是ImageItem组件。

编辑2: 这很奇怪http://codepen.io/anon/pen/eBpdjx这里我只是改了它,所以ImageItem渲染图像元素而不是div上的背景图像,它按预期工作。谁能解释一下有什么区别?

编辑3:

显然这不仅发生在反应应用程序上,而且发生在jquery app上,请看一下:

http://codepen.io/anon/pen/VmvyPZ

当我尝试将图像加载为css的background-image属性时,浏览器不会缓存图像并加载它两次。

1 个答案:

答案 0 :(得分:0)

我面临着完全相同的问题。由于浏览器未保存对已加载图像的引用,因此再次加载了图像。

我所做的就是创建一个全局数组并将所有图像推送到该数组。

现在,此数组是全局数组,浏览器必须维护该数组,直到整个应用程序被销毁为止。

var allImages = [];

function loadImages(imageUrls) {
imageUrls.forEach((q) => {
    const img = new Image();
    img.src = q;
    allImages.push(img);
});}

此后,即使离线,我也可以在其他页面上加载图像。