我正在尝试在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
元素,因为其他事件处理程序和属性已附加到该元素。
如何完成图像加载并解决承诺?
答案 0 :(得分:1)
不确定第二种方法有什么问题以及为什么认为它有问题。我可以想象,如果图像不在缓存中,则它将加载两次:如果您触发同时加载两个图像,则浏览器将无法知道URL的缓存参数,因此应分别为两个元素加载它。但是,如果按顺序加载它们,则第二个应从缓存中拉出,而不是发出单独的请求,除非您的服务器很奇怪并且提供了禁止缓存的标头。
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">
答案 1 :(得分:0)
如果我对您的理解正确,那么是否要在加载完成后渲染图像?也许只是在“ 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)
答案 2 :(得分:0)
我认为您的假设是错误的。无需加载到DOM就可以加载图像。
我略微修改了您的函数,因此它可以使用image标签而不是load事件来解析,并且看起来运行良好:
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。
希望这会有所帮助。