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.

2 ответа

Решение

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

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

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

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

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

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

Это основывается на том факте, что при импорте 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 и добавить вместо него тег script в шаблон. Поскольку вам все равно нужен JS для активации шаблона, это не так уж и много, но это больше похоже на взлом.

Другие вопросы по тегам