PreloadJS 加载图像,但我无法将其插入 DOM
PreloadJS loaded image, but I cannot insert it to DOM
我正在尝试使用 PreloadJS 预加载一张图片,然后将其插入到 DOM a 两次。但我只能插入一张图片。
var queue = new createjs.LoadQueue();
queue.addEventListener('complete', onComplete);
queue.loadManifest([{
id: 'img',
type: 'image',
src: 'https://i.imgur.com/adSrF00g.png',
}, ]);
queue.load();
function onComplete(event) {
var img = queue.getResult('img');
var imgSrc = img.src;
// this code inserts image to the DOM but 404 not found error appears in console
document.getElementById('game').innerHTML = `<img src="${imgSrc}" />`;
// this code do the same thing and 404 also appears
var DOM_img = document.createElement("img");
DOM_img.src = imgSrc;
document.getElementById('game').appendChild(DOM_img);
// this code insert the image to the DOM succesfully
document.getElementById('game').appendChild(img);
// but the last line does nothing - the img tag does not appear in the DOM and nothing error in the console
document.getElementById('game').appendChild(img);
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>
截图:https://i.imgur.com/VQwAABM.jpg
我不明白为什么只出现一张图片。我做错了什么?我怎样才能插入图像 a 两次?谢谢!
这很容易修复,但首先我想向您解释一下。
什么是Blob URLs或Object-URLs ?
Blob URL/Object URL 是允许 Blob 和 File 对象用作 URL 的伪协议图片、二进制数据的下载链接等内容的来源。
在您的情况下,如果您尝试打开这个 src="blob:https://yada.yada"
blob url,它是已加载图像的 src,它会给您一个错误并且无法打开。
是的,我知道 Teo,但是为什么要使用 src 标签怎么可能呢?
嗯,Blob URLs只能由浏览器内部生成。因此,这些元素具有对 Blob 或 File 对象的特殊引用。这些 URL 只能在浏览器的单个实例和同一会话中本地使用(即 page/document 的生命周期)。
所以在这种情况下,src="blob:https://yada.yada"
链接到 LoadQueue
对象创建的 img
标签。
那么,如何在多个元素中使用同一张图片?
In the LoadQueue docummentation我们可以使用getResult()
方法得到一个Blob对象。因此,为了重用 Blob URL 我们可以 "clone" Blob 对象。根据文档,getResult (value, [rawResult=false])
方法被覆盖以接收此 rawResult
可选参数。如果此参数是 true
,该方法将 returns 作为 Blob 对象 的原始结果,而不是格式化结果.如果没有原始结果,将返回格式化结果。
好的,但是如何在 <img>
元素中使用这个 blob?
嗯,我们可以使用URL.createObjectURL()
方法。此方法创建一个包含新 Blob URL 的 DOMString,表示 Blob 对象参数中给定。
正如我上面所解释的,这个 Blob URL 生命周期与 window 中的文档相关联它是在其上创建的。
实现如下:
let queue = new createjs.LoadQueue();
queue.addEventListener('complete', onComplete);
queue.loadManifest([{
id: 'sprite',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, ]);
queue.load();
function onComplete(event) {
// Get Blob object instead of a formatted result
let blob = queue.getResult('sprite', true);
// Create a Blob URL using the Blob object
let urls = [
URL.createObjectURL(blob),
URL.createObjectURL(blob),
URL.createObjectURL(blob),
];
// Create a new <img> element and assign a Blob URL
urls.forEach(function(item, index, array) {
let DOM_img = document.createElement('img');
DOM_img.src = item;
document.getElementById('game').appendChild(DOM_img);
});
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>
替代解决方案(不推荐用于大文件)
您还可以使用 loadManifest()
以不同的 ID 多次加载相同的图像。然后我们定义一个 fileload
事件而不是 complete
事件来捕获每个加载的元素,检查这个例子:
let queue = new createjs.LoadQueue();
queue.addEventListener('fileload', onFileLoad);
queue.loadManifest([{
id: 'sprite1',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, {
id: 'sprite2',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, {
id: 'sprite3',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, ]);
function onFileLoad(event) {
// Get the image element after is successfully loaded
let img = event.result;
// This code insert the image to the DOM succesfully
document.getElementById('game').appendChild(img);
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>
刚刚找到另一个解决方案,加载图像一次,然后将其插入 dom a 两次。
var queue = new createjs.LoadQueue();
queue.addEventListener('complete', onComplete);
queue.loadManifest([{
id: 'img',
type: 'image',
src: 'https://i.imgur.com/adSrF00g.png',
}, ]);
queue.load();
function onComplete(event) {
// get loading results as blob (second argument is set to true)
var blob = queue.getResult('img', true);
// create two blob urls from one blob image source
var blobUrl = URL.createObjectURL(blob);
var blobUrl2 = URL.createObjectURL(blob);
// create new IMG tag and set src as first blob url
var DOM_img = document.createElement("img");
DOM_img.src = blobUrl;
document.getElementById('game').appendChild(DOM_img);
// create new IMG tag and set src as second blob url
var DOM_img2 = document.createElement("img");
DOM_img2.src = blobUrl2;
document.getElementById('game').appendChild(DOM_img2);
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>
我正在尝试使用 PreloadJS 预加载一张图片,然后将其插入到 DOM a 两次。但我只能插入一张图片。
var queue = new createjs.LoadQueue();
queue.addEventListener('complete', onComplete);
queue.loadManifest([{
id: 'img',
type: 'image',
src: 'https://i.imgur.com/adSrF00g.png',
}, ]);
queue.load();
function onComplete(event) {
var img = queue.getResult('img');
var imgSrc = img.src;
// this code inserts image to the DOM but 404 not found error appears in console
document.getElementById('game').innerHTML = `<img src="${imgSrc}" />`;
// this code do the same thing and 404 also appears
var DOM_img = document.createElement("img");
DOM_img.src = imgSrc;
document.getElementById('game').appendChild(DOM_img);
// this code insert the image to the DOM succesfully
document.getElementById('game').appendChild(img);
// but the last line does nothing - the img tag does not appear in the DOM and nothing error in the console
document.getElementById('game').appendChild(img);
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>
截图:https://i.imgur.com/VQwAABM.jpg
我不明白为什么只出现一张图片。我做错了什么?我怎样才能插入图像 a 两次?谢谢!
这很容易修复,但首先我想向您解释一下。
什么是Blob URLs或Object-URLs ? Blob URL/Object URL 是允许 Blob 和 File 对象用作 URL 的伪协议图片、二进制数据的下载链接等内容的来源。
在您的情况下,如果您尝试打开这个 src="blob:https://yada.yada"
blob url,它是已加载图像的 src,它会给您一个错误并且无法打开。
是的,我知道 Teo,但是为什么要使用 src 标签怎么可能呢?
嗯,Blob URLs只能由浏览器内部生成。因此,这些元素具有对 Blob 或 File 对象的特殊引用。这些 URL 只能在浏览器的单个实例和同一会话中本地使用(即 page/document 的生命周期)。
所以在这种情况下,src="blob:https://yada.yada"
链接到 LoadQueue
对象创建的 img
标签。
那么,如何在多个元素中使用同一张图片?
In the LoadQueue docummentation我们可以使用getResult()
方法得到一个Blob对象。因此,为了重用 Blob URL 我们可以 "clone" Blob 对象。根据文档,getResult (value, [rawResult=false])
方法被覆盖以接收此 rawResult
可选参数。如果此参数是 true
,该方法将 returns 作为 Blob 对象 的原始结果,而不是格式化结果.如果没有原始结果,将返回格式化结果。
好的,但是如何在 <img>
元素中使用这个 blob?
嗯,我们可以使用URL.createObjectURL()
方法。此方法创建一个包含新 Blob URL 的 DOMString,表示 Blob 对象参数中给定。
正如我上面所解释的,这个 Blob URL 生命周期与 window 中的文档相关联它是在其上创建的。
实现如下:
let queue = new createjs.LoadQueue();
queue.addEventListener('complete', onComplete);
queue.loadManifest([{
id: 'sprite',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, ]);
queue.load();
function onComplete(event) {
// Get Blob object instead of a formatted result
let blob = queue.getResult('sprite', true);
// Create a Blob URL using the Blob object
let urls = [
URL.createObjectURL(blob),
URL.createObjectURL(blob),
URL.createObjectURL(blob),
];
// Create a new <img> element and assign a Blob URL
urls.forEach(function(item, index, array) {
let DOM_img = document.createElement('img');
DOM_img.src = item;
document.getElementById('game').appendChild(DOM_img);
});
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>
替代解决方案(不推荐用于大文件)
您还可以使用 loadManifest()
以不同的 ID 多次加载相同的图像。然后我们定义一个 fileload
事件而不是 complete
事件来捕获每个加载的元素,检查这个例子:
let queue = new createjs.LoadQueue();
queue.addEventListener('fileload', onFileLoad);
queue.loadManifest([{
id: 'sprite1',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, {
id: 'sprite2',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, {
id: 'sprite3',
type: 'image',
src: 'https://i.imgur.com/ciIyRtu.jpg?1',
}, ]);
function onFileLoad(event) {
// Get the image element after is successfully loaded
let img = event.result;
// This code insert the image to the DOM succesfully
document.getElementById('game').appendChild(img);
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>
刚刚找到另一个解决方案,加载图像一次,然后将其插入 dom a 两次。
var queue = new createjs.LoadQueue();
queue.addEventListener('complete', onComplete);
queue.loadManifest([{
id: 'img',
type: 'image',
src: 'https://i.imgur.com/adSrF00g.png',
}, ]);
queue.load();
function onComplete(event) {
// get loading results as blob (second argument is set to true)
var blob = queue.getResult('img', true);
// create two blob urls from one blob image source
var blobUrl = URL.createObjectURL(blob);
var blobUrl2 = URL.createObjectURL(blob);
// create new IMG tag and set src as first blob url
var DOM_img = document.createElement("img");
DOM_img.src = blobUrl;
document.getElementById('game').appendChild(DOM_img);
// create new IMG tag and set src as second blob url
var DOM_img2 = document.createElement("img");
DOM_img2.src = blobUrl2;
document.getElementById('game').appendChild(DOM_img2);
}
<script src="https://code.createjs.com/1.0.0/preloadjs.min.js"></script>
<div id="game"></div>