自定义组件库中的相对路径

时间:2015-08-10 08:38:05

标签: javascript css relative-path custom-component shadow-dom

我的项目结构看起来像这样

-client
----index.html
----index.ts
-core
----controls
--------myControl.html
--------myControl.ts
----css
--------common.css

myControl.html包含通过shadow dom注册的自定义组件的定义。  在其模板中导入common.css,它是“核心”库的一部分:

<template id="t">
    <style>
        @import url('../css/common.css');
    ....
    </style>
    ....
</template>
<script>
  (function() {
      var importDoc = document.currentScript.ownerDocument; // importee

      var proto = Object.create(HTMLElement.prototype);

      proto.createdCallback = function() 
      {
          // get template in import
          var template = importDoc.querySelector('#t');

          // import template into
          var clone = document.importNode(template.content, true);

          var root = this.createShadowRoot();
          root.appendChild(clone);

          var control = this;

          System.import('core/controls/myControl').then(function(m)
          {
              var t = new m.myControl(control.shadowRoot);
          });
      };

      document.registerElement('my-control', {prototype: proto});
  })();
</script>

现在当我在index.html上使用my-control时,浏览器会抱怨它无法导入common.css。因为它使用相对于index.html的路径搜索它,而不是相对于其originall位置。我理解这是合乎逻辑的,因为我们已经从在index.html上下文中运行的脚本创建了影子dom。

我的问题是:我应该如何开发作为'核心'库的一部分的控制自定义组件,可以在不同的地方重用/分发,并且仍然正确引用css / images /等资源,这些资源也是'核心'库。

提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以使用绝对网址吗?

发布/深度/弃用与您一样,css @injects是我们在组件中应用通用样式的方式。

但如何识别共同风格的路径?

首先给出一些上下文,我们将组件托管在一个硫化的html文件中,客户端使用html导入在其应用程序中使用它。 现在在这个imports.html中我们已经包含了一个小脚本,它使用document.currentScript.ownerDocument.baseURI标识自己的URL,并且因为我们知道imports.html的常见css相对路径,所以我们动态构造这个url并注入构造的样式标签在模板中包含css @imports。

这样,当组件更新时(阴影根连接到它),它会调用下载common.css(因为它知道绝对URL)并在阴影dom中使用它

因此,总结一下不使用css @import模板内部的硬编码样式标签,根据您当前输入的html网址构建它并将其注入模板内。

或许这样的事情:

//URL of your html import or script being executed.
var host = document.currentScript.ownerDocument.baseURI;
//splice and dice your host url to get protocol and base url
...
// let's say it is proto and base
var cssURL = proto + base + '/core/css/common.css'
// construct a style tag here with css imports.
// Since you have access to document-fragment coming with html import
// find template and inject this style tag inside it.
// Remember to inject it at top :)