Изображения, созданные с использованием `document.currentScript.ownerDocument.createElement` (из <link> импортированного HTML), никогда не загружаются

Вот функция, которая возвращает ширину изображения, учитывая его URL:

async function getImageWidthByUrl(imgUrl) {
  const imgEl = document.createElement("img");
  let untilImgLoaded = new Promise((resolve, reject) => {
    imgEl.onload = resolve;
    imgEl.onerror = reject;
  });
  imgEl.src = imgUrl;
  await untilImgLoaded;
  return imgEl.naturalWidth;
}

Работает нормально. Это также (конечно) работает, если мы используем new Image() вместо document.createElement("img"),

Тем не менее document.createElement("img") метод не работает, если document относится к объекту документа <link> Импорт HTML.

Посмотрите на этот пример, который импортирует этот HTML. Обратите внимание, что консоль выводит:

"Starting..."
512
512

и никогда не выводит финал 512 а потом "Finished."Вроде бы (похоже) должен. Это потому что onload событие imgEl никогда не стреляет; изображение никогда не загружается, если оно было создано с document.currentScript.ownerDocument.createElement, Я проверял это в Chrome 69.

Это ожидаемое поведение или ошибка? Не должно ли это, по крайней мере, выдать ошибку, если невозможно создать изображение, используя <link>"s document?

1 ответ

Решение

Это нормальное поведение.

Изображение, указанное в src атрибут <img> элемент в импортированном документе с <link rel="import"> не загружается, пока не будет добавлен к основному документу.

Из учебника по импорту HTML:

Думайте о контенте как о инертном, пока не воспользуетесь его услугами. [...]

Если вы не добавите его содержимое в DOM, это не будет. Фактически, единственное, что "выполняется" в документе импорта напрямую, это <script>,

Вы можете добавить его к основному документу с помощью document.apendNode(),

Также обратите внимание, что в вашем примере вы должны передать импортированную ссылку на документ в качестве аргумента основной функции simple-test.html по некоторым причинам, объясненным в этом или том посте.

( function( ownerDocument ) {
    //...
    if( method === "document.currentScript.ownerDocument.createElement") {
        imgEl = ownerDocument.createElement("img")
        var imgOK = document.adoptNode( imgEl )
    }
    //...  
} ) ( document.currentScript.ownerDocument )
Другие вопросы по тегам