简体   繁体   English

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

[英]preload images on javascript (React, Jquery) app, images loaded twice

  • Please look at EDIT 3 below, as I figured out that it is not an issue with React but with the browser's chaching mechanism. 请查看下面的EDIT 3,因为我发现这不是React的问题,而是浏览器的缓存机制。

I'm trying to create an app that creates some simple carousel out of given array of images url. 我正在尝试创建一个应用,该应用根据给定的图像网址数组创建一些简单的轮播。 I've written a module that helps me to invoke a callback once all the images are loaded, this is how it look: 我编写了一个模块,该模块可帮助我在加载所有图像后调用回调,如下所示:

ImagesLoader.js 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;
        });
    }
}

I know I can use promises and resolve once all urls are loaded, and no check for errors right now. 我知道一旦所有网址加载完毕,我就可以使用promises并进行解析,并且现在不检查错误。

Here is where my component updates the state with the images retriveed from the module above: 这是我的组件使用从上述模块中检索到的图像更新状态的地方:

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

What happens is when I click the next or previous button (look at the screenshot below) each time the image loaded again, I can't understand why. 发生的情况是,每次图像再次加载时,我都单击“下一个”或“上一个”按钮(请参见下面的屏幕快照),我不知道为什么。

this is the first time I do such thing with reactjs, with jquery had no problems 这是我第一次用reactjs做这样的事情,用jquery没问题

Chrome上的“网络”标签

Here is how I pass the images urls: 这是我传递图片网址的方法:

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

EDIT: managed to give a short example. 编辑:设法举一个简短的例子。 http://codepen.io/anon/pen/ObyRPX , what I could see from building this example is if I don't use the ImageItem component and render a simple <img src='image.src'/> element it works good, so I guess my problem is with the ImageItem component. http://codepen.io/anon/pen/ObyRPX ,从构建此示例中可以看到的是,如果我不使用ImageItem组件并渲染一个简单的<img src='image.src'/>元素,则它可以工作好,所以我想我的问题出在ImageItem组件上。

EDIT 2: this is pretty weird http://codepen.io/anon/pen/eBpdjx here I just changed it so ImageItem renderes image element rather than background image on a div and it works as expected. 编辑2:这是很奇怪的http://codepen.io/anon/pen/eBpdjx在这里,我只是更改了它,所以ImageItem在div上渲染图像元素而不是背景图像,并且按预期工作。 Can anyone explain what is the difference? 谁能解释有什么区别?

EDIT 3: 编辑3:

Apparently this is happening not only on react apps but on jquery app aswell, have a look here: 显然,这不仅在react应用程序上发生,而且也在jquery应用程序上发生,请看这里:

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

Again when I try to load the image as background-image property of the css, the browser doesn't cache the image and load it twice. 同样,当我尝试将图像作为css的background-image属性加载时,浏览器不会缓存图像并加载两次。

I faced the exact same issue. 我面临着完全相同的问题。 The image gets loaded again because the browser is not holding a reference to the image that you have loaded. 由于浏览器未保存对已加载图像的引用,因此再次加载了图像。

All I did was create a global array and push all the images to the array. 我所做的就是创建一个全局数组并将所有图像推送到该数组。

Now, this array is global and the browser has to maintain the array until the whole app gets destroyed. 现在,此数组是全局数组,浏览器必须维护该数组,直到整个应用程序被销毁为止。

var allImages = [];

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

After this, I was able to load the images on other pages, even when offline. 之后,即使离线,我也可以将图像加载到其他页面上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM