加载没有 "new Image()" 的图像

Load image without "new Image()"

我正在尝试加载 JavaScript 中的图像:

loadImage(src, img) {
  return new Promise((resolve, reject) => {
    img.onload = resolve;
    img.onerror = reject;
    img.src = src;
  });
}

img 之前已创建,但 DOM 中尚不存在。它应该在加载后附加。

我的问题: 据我了解,它实际上不会加载图像,因为该元素还不是 DOM 的一部分。


我尝试使用new Image(),因为这会在插入DOM之前加载图像源:

loadImage(src, img) {
  return new Promise((resolve, reject) => {
    var tmp = new Image();

    tmp.onload = resolve;
    tmp.onerror = reject;
    tmp.src = src;
    img.src = src;
  });
}

然而,这加载了两次并且感觉有问题。

我需要保留(并使用)img 元素,因为它附加了其他事件处理程序和属性。

我该怎么做才能加载图像并在完成后解决承诺?

如果我没理解错的话,你想在加载完成后渲染图像吗?也许只是在 "loadImage" 函数中创建图像,然后在 "onload" 中进行适当的附加。这是我在想的一个例子:

const loadImage = (src, parentEl) => {
const img = document.createElement('img')
img.src = src
img.onload = () => {
  parentEl.appendChild(img)
 }
}

const parentEl = document.getElementById('parent')
loadImage('https://fakeimg.pl/640x360', parentEl)

https://jsfiddle.net/2Lp8hyxf/

不确定您的第二种方法有什么问题以及为什么您认为它有问题。我可以想象如果图像不在缓存中它会加载两次:如果您同时触发加载两个图像,浏览器无法知道 URL 的缓存参数,应该分别为两个元素加载它.但是如果你按顺序加载它们,第二个应该从缓存中提取,而不是发出单独的请求,除非你的服务器很奇怪并且服务 headers 禁止缓存。

function loadImage(src, img) {
  return new Promise((resolve, reject) => {
    var tmp = new Image();

    tmp.onload = () => {
      img.src = src;
      resolve();
    };
    tmp.onerror = reject;
    tmp.src = src;
  });
}

loadImage("https://via.placeholder.com/350x150", document.getElementById('foo'));
<image id="foo">

我认为你的假设是错误的。图片无需附加到 DOM 即可加载。

我稍微修改了你的函数,所以它用图像标签而不是加载事件来解析,它似乎工作正常:

const loadImage = (src, img) => {
    return new Promise((resolve, reject)=> {
    img.src = src
    img.onload = () => {
        resolve(img);
    }
    img.onerror = reject;
  })

}

我是这样测试的:

const img = document.createElement('img');
loadImage('http://deelay.me/1500/https://fakeimg.pl/640x360', img)
    .then((img) => {
    const parent = document.getElementById('parent');
    document.getElementById('parent').append(img);
    const text = document.createElement('p');
    text.innerText = "The promise resolved now";
    parent.append(text);
  })

deelay.me 人为延迟了图像的加载,因此您可以看到图像实际上已加载,并且使用 promise,仅在图像加载后才附加到 DOM已加载。

希望这对您有所帮助。

Fiddle: https://jsfiddle.net/f4hratje/5/