将同一小部件​​的多个实例插入到页面中

Insert multiple instances of a same widget into a page

我有一个小部件,它在指向特定 datasource/API 后呈现条形图 (HTML/CSS/JavaScript)。有一个配置参数可以更改 datasource/API,因此我可以拥有同一个小部件的多个实例。

是否可以使用 shadow-dom 来完成上述操作?我尝试了以下操作,但注意到小部件无法 select 正确的 div 元素来完成渲染部分。

        var host = document.querySelector("#" + gadgetContainer.getAttribute("data-grid-id"));
        var root = host.createShadowRoot();

        var template = document.createElement('template');
        template.innerHTML = gadgetContainer.outerHTML; 
        root.appendChild(document.importNode(template.content, true));

以下是执行小部件渲染的 JavaScript 逻辑,为了清楚起见,我删除了数据集和配置。

(function () {
    "use strict";
    //dataset used to plot charts
    var dataTable = {}, //REMOVED
        width = document.querySelector('*::shadow #bar').offsetWidth,
        height = 270,   //canvas height
        config = {}; //REMOVED
    widget.renderer.setWidgetName("bar-chart", "BAR CHART");

    chartLib.plot("*::shadow #bar",config, dataTable);
}());

以下是简单的HTML div,所有必需的样式表和脚本都在这个页面中。

<div id="bar" class="bar"></div>

这里是重用模板的最小示例,使用 Shadow 创建同一小部件​​的 2 个实例 DOM:

var template = document.querySelector( 'template' )

target1.attachShadow( { mode: 'open' } )
       .appendChild( template.content.cloneNode( true ) )
       
target2.attachShadow( { mode: 'open' } )
       .appendChild( template.content.cloneNode( true ) )
<template>
  <style>
    :host { display: inline-block; width:100px; height:50px ; border: 1px solid gray; }
    header { color: blue; font-size:15px; font-weight: bold; }
    section { color: gray; font-size:12px ; }
  </style>
  <header>
     Widget <slot name="number"></slot>
  </header>
  <section>
     Content
  </section>
</template>

<div id="target1"><span slot="number">1</span></div>

<div id="target2"><span slot="number">2</span></div>

请注意,您应该使用 Shadow DOM "v1" 和 attachShadow() 而不是 createShadowRoot(),因为它是将在 [= 以外的浏览器上实施的标准规范28=]。旧版本以后会弃用

使用<slot>获取lightDOM的内容,插入到ShadowDOM中。