PreloadJS загрузил изображение, но я не могу вставить его в DOM - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь предварительно загрузить одно изображение с помощью PreloadJS , а затем вставить его в 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) {
  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

Я не могу понять, почему появляется только одно изображение. Что я делаю не так? И как я могу вставить изображение дважды? Спасибо!

Ответы [ 2 ]

2 голосов
/ 12 июня 2019

Это легко исправить, но сначала я хочу кое-что вам объяснить.

Что такое URL-адреса BLOB-объектов или URL-адреса объектов? Blob URL / Object URL - это псевдопротокол, позволяющий использовать объекты Blob и File в качестве источника URL для таких вещей, как изображения, ссылки для загрузки двоичных данных и т. Д.

В вашем случае, если вы попытаетесь открыть этот URL-адрес BLOB-объекта src="blob:https://yada.yada", являющийся источником загруженного изображения, он выдаст вам ошибку и его не удастся открыть.

Да, я знаю, что Teo, но почему, если это работает с тегом src, как это возможно?

Ну, URL-адреса BLOB-объектов могутгенерироваться только внутри браузера.Таким образом, эти элементы имеют специальную ссылку на объект Blob или File.Эти URL-адреса могут использоваться только локально в одном экземпляре браузера и в одном и том же сеансе (т. Е. В жизни страницы / документа).

Так что в этом случае src="blob:https://yada.yada" связан с img тег, созданный объектом LoadQueue.

Тогда, как я могу использовать одно и то же изображение в нескольких элементах?

В документации LoadQueue , которую мы можем получить Объект BLOB с использованием метода getResult().Таким образом, вместо повторного использования BLOB-URL мы можем "клонировать" объект BLOB-объекта .Согласно документации методы getResult (value, [rawResult=false]) были перезаписаны для получения этого необязательного параметра rawResult.Если этот параметр равен true, метод возвращает необработанный результат в виде объекта BLOB-объекта вместо отформатированного результата.Если нет необработанного результата, вместо него будет возвращен отформатированный результат.

ОК, но как я могу использовать этот BLOB-объект в элементе <img>?

Что ж, мы можем использовать URL.createObjectURL() метод.Этот метод создает строку DOMString, содержащую новый URL-адрес BLOB-объекта , представляющий объект BLOB-объекта , указанный в параметре.

AsЯ объяснил выше, этот URL-адрес BLOB-объекта время жизни привязан к документу в окне, в котором он был создан.

Вот реализация:

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() для загрузки одного и того же изображения несколько раз с разнымиидентификаторы.Затем мы определяем событие 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>
0 голосов
/ 13 июня 2019

Только что нашли другое решение, которое загружает изображение один раз, а затем вставляет его в 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...