Шаблоны HTML и импорт HTML — внутренний скрипт не выполняется в Firefox

Я использую webcomponents.js для полифилла поддержки Firefox веб-компонентов.

При загрузке шаблона HTML посредством импорта HTML сценарий в шаблоне не выполняется, как только настраиваемый элемент, основанный на шаблоне, добавляется в DOM главной страницы.

Он выполняется при запуске сайта в Chrome (который имеет встроенную поддержку веб-компонентов).

Однако и Firefox, и Chrome выполняют такой скрипт, когда шаблон размещается на самой главной странице.

См. пример Эрика Бидельманна на странице HTML5Rocks. Это работает как в Chrome, так и в Firefox (через webcomponents.js) — если шаблон находится в одном HTML-файле.

<!DOCTYPE html>
<html>
<body>

<button onclick="useIt()">Use me</button>
<div id="container"></div>
<script>
  function useIt() {
    var content = document.querySelector('template').content;
    // Update something in the template DOM.
    var span = content.querySelector('span');
    span.textContent = parseInt(span.textContent) + 1;
    document.querySelector('#container').appendChild(
        document.importNode(content, true));
  }
</script>

<template>
  <div>Template used: <span>0</span></div>
  <script>alert('Thanks!')</script>
</template>



</body>
</html>

Но хотя отображается текст шаблона, он НЕ запускается при загрузке шаблона и его содержимого через ссылку импорта HTML. Как уже упоминалось, он загружает содержимое, но не выполняет скрипт в Firefox.

Это ошибка в webcomponents.js или ошибка в Firefox? У кого-нибудь есть хорошая идея для обходных путей (кроме «использовать Polymer или Angular»)?

Примечание. Это основано на использовании Firefox 43 и Chrome 47.


person nepdev    schedule 27.01.2016    source источник
comment
IDK, у меня отлично работает на Firefox 42, OSX: jsfiddle.net/tuq0wj1y   -  person Korgrue    schedule 28.01.2016
comment
Вышеприведенный пример, как показано, работает в Firefox и Chrome. Что не работает, так это помещение элемента ‹template› в отдельный файл и его загрузка с помощью импорта HTML (элемент ссылки с rel=import)   -  person nepdev    schedule 28.01.2016
comment
Получаете ли вы какие-либо оповещения песочницы в консоли?   -  person Korgrue    schedule 28.01.2016


Ответы (2)


Это не ошибка в Firefox, Internet Explorer 11 имеет такое же поведение (с webcomponents.js).

Метод importNode не является полифиллом webcomponents.js. Вот почему <script> элементы не активируются при импорте.

Открылась ошибка, связанная с этой проблемой.

Мой обходной путь: я не вставляю теги скриптов <script> в импортированный <template> (разделенный JS/HTML:).

Кроме того, вы можете проанализировать свой <template> в поисках <script> тегов и попытаться активировать/выполнить их вручную (это может быть несколько сложно...)

person Supersharp    schedule 28.01.2016

Я нашел обходной путь для этой проблемы, который позволяет выполнять скрипт при активации элемента шаблона.

Это основано на том факте, что HTML-импорт немедленно выполняет сценарии, расположенные в импортированном файле, если они не находятся внутри тега шаблона. Таким образом, решение состоит в том, чтобы просто добавить еще один импорт HTML в файл импорта и загрузить скрипт в качестве внешнего ресурса — он загружается, как только шаблон активируется и выполняется прямо здесь и сейчас.

Поэтому вместо того, чтобы иметь во внешнем файле импорта следующее:

<template>
  <div>Template used: <span>0</span></div>
  <script>alert('Thanks!')</script>
</template>

у вас ЭТО:

<template>
  <div>Template used: <span>0</span></div>
  <link rel="import" href="script1.html">
</template>

а указанный файл script1.html содержит следующее:

  <script>
      alert('Thanks!')
  </script>

Да, это еще один HTTP-запрос, но он рабочий и простой.

Это решает любой скрипт, который должен запускаться при инициализации элемента шаблона. Сценарий, необходимый для последующей активации, может быть реализован в виде определений функций или встроенных сценариев.

Примечание.
Другим обходным решением является добавление тега "div" во внешний файл импорта ниже (и вне) раздела шаблона с id="script1", а затем использовать JS для извлечения содержимого div и добавления тега скрипта. вместо этого в шаблон. Поскольку вам в любом случае нужен JS для активации шаблона, это не так уж много изменений, но это больше похоже на взлом.

person nepdev    schedule 30.01.2016
comment
Вот (один из способов) того, как правильно подать приготовленную еду вместо этого сырого мусора: import-›cooked-template = RAW. Когда я создаю модуль, я ожидаю, что этот модуль будет работать одинаково, независимо от того, как я его загружаю. К счастью, мой проект находится в локальной файловой системе, поэтому я не беспокоюсь о запросах на вытягивание, просто все обслуживается так, как эти предметы были приготовлены. - person Hypersoft Systems; 07.11.2017
comment
однако это усложняет написание кода в отношении заполнения шаблона. - person Hypersoft Systems; 07.11.2017
comment
это странный обходной путь, который почему-то кажется небезопасным, но я не нашел веских причин не использовать его, кроме неуклюжей архитектуры. - person Felipe; 10.05.2019