Пути в веб-компонентах относительно корня
Я создаю веб-компонент, используя нативную реализацию, которая в своем html-шаблоне имеет ссылки на изображения. Однако эти ссылки работают только в том случае, если они являются абсолютными или относительными к основному документу, что означает, что этот компонент не может быть повторно использован или переносим. Кроме того, это очень нелогично.
В настоящее время я добавляю атрибут data-url_prefix ко всем элементам, которые должны использовать изображения. Затем, при создании теневого корня для моего пользовательского элемента, я заменяю {{URL_PREFIX}} значением об этом споре.
Мое решение кажется очень плохим. Я был бы очень рад, если бы вы посоветовали что-нибудь получше, спасибо.
Я нашел интересную цитату на http://webcomponents.org/polyfills/html-imports/ Страница:
ЗАМЕТКИ О ПОЛИФИЛЕ
В импортированных документах атрибуты href и src в HTML и url свойства в CSS файлах, являются относительными к местоположению импортируемого файла. документ, а не основной документ.
Зачем полифил использовать иную логику, чем родная реализация?
Веб-компоненты в идеале должны инкапсулировать все свои зависимости, но если веб-компоненту требуется изображение, он должен знать абсолютный URL-адрес этого изображения, что не позволяет компоненту просто перемещаться по файловой структуре.
Скажем, например, у меня есть следующее структура:
- индекс.html
- css
- главная.css
- js
- главная.js
- web_компоненты
- cool_web_компонент
- cool_web_компонент.html
- икона.png
- cool_web_компонент
Если я изменю его на следующее:
- индекс.html
- css
- главная.css
- js
- главная.js
- cool_web_компонент
- cool_web_компонент.html
- икона.png
Мне потребуется изменить указатель на значок.png где-то в этих файлах Мой вопрос заключается в том, как избежать этого или решить его элегантным способом. Кроме того, почему фактическая нативная реализация находится в конфликте с полифиллами?
2 ответа:
Спецификация вебкомпонента определяет, что URL-адреса всегда относятся к основному документу. Это, конечно, нарушает инкапсуляцию веб-компонентов, как вы правильно заключили. Другими словами, спецификация глючит, и многие люди жалуются на это. Вот почему полифилл не следует спецификации: он исправляет проблему.
Спецификация изменится. Однако, поскольку это не тривиально исправить, это все еще может занять некоторое время. Пожалуйста, посмотрите на это ссылки:
• https://lists.w3.org/Archives/Public/public-webapps/2014OctDec/0013.html
• https://www.w3.org/Bugs/Public/show_bug.cgi?id=20976#c8
На данный момент решение заключается в том, чтобы ваш компонент изменил URL-адрес своих шаблонов изображений с относительного на абсолютный. Вы можете получить
templateBaseUrl
следующим образом:(function (window, document) { var proto = Object.create(HTMLElement.prototype); var template = document.currentScript.ownerDocument.querySelector("template"); var templateBaseUrl = template.baseURI; proto.createdCallback = function () { // Now find all images inside the template and change their src attribute, // using templateBaseUrl. Also you must change CSS background-image: url(...); ... }; document.registerElement('test-element', {prototype: proto}); })(window, document);
Другой способ исправить это, в случае небольших изображений, таких как значки, заключается в том, чтобы встроить данные изображения непосредственно в документ, с помощью данные URIs . Это также сохраняет HTTP-запросы (пока у нас нет Http/2). Например:
<img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />
Такое поведение, по-видимому, характерно только для изображений.
Для тегов сценариев и ссылок относительные пути из импортированного документа работают должным образом.Также я заметил, что это не является чем-то специфичным для polyfills, даже для родной реализации (chrome) эта проблема(?) кажется, есть.
Похоже, что единственным вариантом здесь является включение скрипта в импортированный html, который преобразует эти относительные пути в их абсолютные аналоги.
Поэтому, чтобы ответить на ваш второй вопрос, я не вижу никакой разницы в нативной и полифилированной реализации, по крайней мере, с точки зрения поведения атрибутов
Чтобы решить ее элегантно, вы можете избежать жесткого кодирования URL-адреса в вашем скрипте и генерировать его с помощью url-адреса импортируемого документа. Вы можете получить это изdocument.currentScript.ownerDocument
(илиdocument._currentScript.ownerDocument
в сценарии polyfilled).src
иhref
.
Цитата, которую вы упомянули из http://webcomponents.org/polyfills/html-imports/, похоже, специфичен для href / src тегов скриптов и ссылок, и они работают как написанный.Надеюсь, это поможет.