【问题标题】:Preload images and prevent downloading same image multiple times in JavaScript预加载图像并防止在 JavaScript 中多次下载相同的图像
【发布时间】:2021-09-24 00:01:49
【问题描述】:

我正在构建一个包含图片库的 Angular 应用程序。基本上是一个图像和两个按钮,上一个图像和下一个图像。以下是此类画廊的一些非常简单的代码(无 Angular):

<html>
<style>
    img {
        display: block;
        height: 300px;
    }
</style>

<body>
    <img id="img"></img>
    <button id="prevB">Prev</button>
    <button id="nextB">Next</button>

    <script>
        var arr = [
            "https://firebasestorage.googleapis.com/v0/b/animaps-e8f7a.appspot.com/o/EugywRZ814yCMrMhopVF%2F3c.jfif?alt=media&token=d6ab88bc-5065-4dbc-ab9d-884a9af1380b",
            "https://firebasestorage.googleapis.com/v0/b/animaps-e8f7a.appspot.com/o/4KzYH8gMDjhKHFrTIXlB%2F1c.jpg?alt=media&token=9cd7bed2-c645-408c-acd5-77fdd9370389",
            "https://firebasestorage.googleapis.com/v0/b/animaps-e8f7a.appspot.com/o/ftGGK4Wj1ski8lJi1TRE%2F5a.jfif?alt=media&token=4a36d9c5-924f-4738-9851-cf057de74544",
        ]

        var index = 0;
        document.getElementById("prevB").addEventListener("click", () => {
            index--;
            document.getElementById("img").src = arr[index % arr.length];
        });
        document.getElementById("nextB").addEventListener("click", () => {
            index++;
            document.getElementById("img").src = arr[index % arr.length];
        });
        document.getElementById("img").src = arr[index];
    </script>
</body>

问题一:为什么浏览器会多次下载同一张图片?每次我单击 Prev 或 Next 时,图像都会再次下载,即使它已经下载。有没有办法指示浏览器缓存(保存)下载的图像?

问题 2:有没有办法(Angular 特定或纯 JS)预加载整个图像列表?即在页面加载时下载所有图片,然后点击下一步立即看到下一张图片。

【问题讨论】:

    标签: javascript angular image


    【解决方案1】:

    问题一:为什么浏览器会多次下载同一张图片?

    很可能是因为您打开了控制台,并选择了禁用缓存。无论是那个还是后端都在设置某种cache-control header

    问题 2:有没有办法(Angular 特定或纯 JS)预加载整个图像列表?

    当然——我可能会在 JS 中创建 img 元素,然后只换掉你预先创建的图像(而不是仅仅在同一张图像上切换 src),就像这样:

    const createImg = (src) => {
         const img = document.createElement('img');
         img.src = src;
         img.id="img";
         return img;
     }
     
     var arr = [
                "https://firebasestorage.googleapis.com/v0/b/animaps-e8f7a.appspot.com/o/EugywRZ814yCMrMhopVF%2F3c.jfif?alt=media&token=d6ab88bc-5065-4dbc-ab9d-884a9af1380b",
                "https://firebasestorage.googleapis.com/v0/b/animaps-e8f7a.appspot.com/o/4KzYH8gMDjhKHFrTIXlB%2F1c.jpg?alt=media&token=9cd7bed2-c645-408c-acd5-77fdd9370389",
                "https://firebasestorage.googleapis.com/v0/b/animaps-e8f7a.appspot.com/o/ftGGK4Wj1ski8lJi1TRE%2F5a.jfif?alt=media&token=4a36d9c5-924f-4738-9851-cf057de74544",
            ].map(createImg);
    
            var index = 0;
            document.getElementById("prevB").addEventListener("click", () => {
                index--;
                const img = document.getElementById("img");
                img.parentNode.replaceChild( arr[index % arr.length], img);
            });
            document.getElementById("nextB").addEventListener("click", () => {
                index++;
                const img = document.getElementById("img");
                img.parentNode.replaceChild( arr[index % arr.length], img);
            });
            img.parentNode.replaceChild( arr[index % arr.length], img);
    #img {
        width: 400px;
    }
    <img id="img"></img>
        <button id="prevB">Prev</button>
        <button id="nextB">Next</button>

    【讨论】:

    • 正确。我在开发工具中检查了“禁用缓存”。取消选中它,现在我得到了我想要的行为。问题 2 的解决方案也完全如我所愿。谢谢:)
    • 其实我还有一个问题,关于问题2。考虑到启用了缓存,只在JS中加载图像而不实际替换img元素是否不够?因此,在加载页面时,对所有图像执行类似document.createElement('img').src = src 的操作。新元素未使用,但图像已下载(并缓存?)。然后点击下一步时仍然做document.getElementById("img").src = srcArray[index % arr.length];
    • jsFiddle 表明我的意思。结果确实不一致。您可以清楚地看到所有 5 张图片在页面加载时都已下载,但单击“下一步”时,有时会再次下载 / 有时不会。很有趣,很想知道是什么导致了这种不一致的行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    相关资源
    最近更新 更多