PreloadJS已加载图像,但无法将其插入DOM

时间:2019-06-11 23:47:41

标签: javascript html createjs preloadjs

我正在尝试使用 PreloadJS 预加载一张图像,然后将其两次插入DOM。但是我只能插入一张图像。

relative
z-index: 2

屏幕截图:https://i.imgur.com/VQwAABM.jpg

我不明白为什么只出现一张图像。我做错了什么?又如何两次插入图像?谢谢!

2 个答案:

答案 0 :(得分:2)

这很容易解决,但首先我想向您解释一下。

什么是 Blob URL 对象URL Blob URL /对象URL 是一种伪协议,允许将Blob和File对象用作诸如图像,二进制数据下载链接之类的URL源。 / p>

在您的情况下,如果尝试打开此src="blob:https://yada.yada" Blob URL(即已加载图像的src),则会出现错误,并且无法打开。

是的,我知道Teo,但是为什么要使用src标签呢?

嗯, Blob URL 只能由浏览器在内部生成。因此,这些元素具有对Blob或File对象的特殊引用。这些网址只能在浏览器的单个实例和同一会话(即页面/文档的生存期)中本地使用。

因此,在这种情况下,src="blob:https://yada.yada"链接到img对象创建的LoadQueue标签。

然后,如何在多个元素中使用相同的图像?

In the LoadQueue docummentation,我们可以使用getResult()方法获得 Blob对象 。因此,代替重用 Blob URL ,我们可以“克隆” Blob对象 >。根据文档,getResult (value, [rawResult=false])方法被覆盖以接收此rawResult可选参数。如果此参数为true,则该方法将返回原始结果作为 Blob对象 ,而不是格式化结果。如果没有原始结果,则将返回格式化结果。

好,但是如何在<img>元素中使用此blob?

好吧,我们可以使用URL.createObjectURL()方法。此方法将创建一个DOMString,其中包含一个新的 Blob URL ,该参数表示参数中给出的 Blob对象

如上所述,此 Blob URL 生存期与创建该文档的窗口中的文档相关。

这是实现:

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>

答案 1 :(得分:0)

刚刚找到了另一种解决方案,该解决方案可以加载一次图像,然后将其插入dom两次。

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>