导入serval webcomponent

时间:2016-03-11 09:32:39

标签: javascript web web-component

当单个页面中有多个自定义元素时,为什么总是显示最后一个元素而前一个元素被覆盖。例如:

第一个组件:

<template id="cmpt-1">
  webcomponent 1
</template>
<script type="text/javascript">
  var thatDoc = document;
  var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
  var t = thisDoc.querySelector('#cmpt-1');

  var protos = Object.create(HTMLElement.prototype, {
    createdCallback: {
      value: function() {
        var clone = thatDoc.importNode(t.content, true);
        this.createShadowRoot().appendChild(clone);
      }
    }
  });
  thatDoc.registerElement('cmpt-1', {
    prototype: protos
  }); 
</script>

第二部分:

<template id="cmpt-2">
  webcomponent 2
</template>
<script type="text/javascript">
  var thatDoc = document;
  var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
  var t = thisDoc.querySelector('#cmpt-2');

  var protos = Object.create(HTMLElement.prototype, {
    createdCallback: {
      value: function() {
        var clone = thatDoc.importNode(t.content, true);
        this.createShadowRoot().appendChild(clone);
      }
    }
  });
  thatDoc.registerElement('cmpt-2', {
    prototype: protos
  }); 
</script>

在单页中导入这两个组件时,例如:

导入组件

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
  <link rel="import" href="cmpt1.html">
  <link rel="import" href="cmpt2.html">
</head>

<body>
  <cmpt-1></cmpt-1>
  <cmpt-2></cmpt-2>
</body>

</html>

然后只显示“组件2”,第二个元素覆盖第一个元素。

2 个答案:

答案 0 :(得分:1)

在立即调用的函数表达式中对脚本标记中的代码进行包装以限制范围可以解决您的问题。

<template id="cmpt-2">
    webcomponent 2
</template>
<script type="text/javascript">
    (function() {
        var thatDoc = document;
        var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
        var t = thisDoc.querySelector('#cmpt-2');

        var protos = Object.create(HTMLElement.prototype, {
            createdCallback: {
                value: function() {
                    var clone = thatDoc.importNode(t.content, true);
                    this.createShadowRoot().appendChild(clone);
                }
            }
        });
        thatDoc.registerElement('cmpt-2', {
            prototype: protos
        });
    })();

</script>

'cmpt-1'是相同的。

答案 1 :(得分:1)

您可以在全局范围内定义所有变量 - 两次,实际上protos是在呈现组件时指向第二个组件的指针。 quickfix会将每个protos重命名为cmpt1cmpt2之类的合理内容,并在thatDoc.registerElement中引用正确的var。更好的解决方案是创建一个通用函数,初始化自定义组件并完全避免全局范围。