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 для активации шаблона, это не так уж и много, но это больше похоже на взлом.