标签: web-component

设置自定义 HTML 元素的样式

我创建了一个普通的自定义元素:

document.registerElement("my-el", { prototype: Object.create(HTMLElement.prototype) }); 
Run Code Online (Sandbox Code Playgroud)

该元素使用 Shadow DOM 和<style>其中的标签。但是,我想让用户在主样式表中定义自定义元素的大小。它通过引用自定义标签来工作,但这是执行此类操作的推荐方法吗?

例如:

my-el {
  width: 300px;
  height: 50px;
  background: green;
}
Run Code Online (Sandbox Code Playgroud)

css web-component shadow-dom custom-element

5
推荐指数
1
解决办法
4959
查看次数

延迟加载 Web 组件

我们有一个巨大的 Web 组件 (2MB) 当前正在元素中加载<head>,但这极大地减少了页面加载时间。

我在想我们是否可以以某种方式延迟加载我们的 Web 组件?

web-component

5
推荐指数
1
解决办法
5222
查看次数

使用纸张输入选择的访问文件

我正在尝试上传通过Polymer <paper-input type="file" id="filepicker">元素选择的文件但是当我尝试访问该文件时:

var file = this.$.filepicker.files
Run Code Online (Sandbox Code Playgroud)

我收到一个files is not defined错误.

我还没有找到任何其他方法来访问纸张输入中的文件,所以我不确定这里的问题是什么.

任何帮助,将不胜感激!

javascript web-component polymer

5
推荐指数
1
解决办法
1120
查看次数

创建具有不同子类型的自定义元素

我目前正在使用自定义元素(Web 组件)实现数据表元素。表格可以具有用于呈现每一行的不同类型的单元格(文本、数字、日期等)。

例如

<my-table>
    <my-table-cell-text column="name"></my-table-cell-text>
    <my-table-cell-date column="dob" format="YYYY-MM-DD"></my-table-cell-date>
    <my-table-cell-number column="salary" decimals="2"></my-table-cell-number >
</my-table>
Run Code Online (Sandbox Code Playgroud)

我还有一个MyTableCell所有单元格元素都扩展的类。这适用于共享通用功能,但样式可能很麻烦,因为每个单元格类型都是它自己的 html 标签。目前,我在扩展时添加了一个 css 类MyTableCell,但为了论证,可以说我不想这样做。

理想的解决方案是能够扩展自定义元素,使用is关键字,例如<my-table-cell is="my-table-cell-text">但只允许内置 html 元素


我可以想到解决这个问题的 3 种方法:

  1. 具有类似于 的语法<input type="">,但需要做更多的工作,因为您不再扩展基类,而是创建相同元素的变体,这意味着您需要一种自定义方式来注册不同的变体,例如静态MyTableCell.registerType

  2. 一种可组合的方法,我将渲染器元素 包裹<my-table-renderer-text>在通用<my-table-cell>. 这避免了自定义注册方法,但它更难编写,并导致更多元素和更多样板代码,这反过来意味着性能下降。

  3. 两者的混合,用户写入<my-table-cell type="text">和单元格在document.createElement('my-table-rendener-'+ type)内部使用类似的东西。这保留了选项 1 的更简单的语法,同时仍然避免了自定义寄存器方法,但它具有与选项 2 相同的性能影响。


你能提出更好的选择吗?我错过了什么吗?

html css dom web-component custom-element

5
推荐指数
1
解决办法
2030
查看次数

为什么 attributeChangedCallback 被调用两次?

我正在使用自定义元素 polyfill构建一个简单的自定义元素。我已经注册了一个要“监视”的属性(使用observedAttributes()),当我更改此属性的值时,该函数会attributeChangedCallback被调用两次。

这是 HTML 代码:

<my-component id="compo" foo="bar"></my-component>

<button id="myBtn">Change attribute value</button>
Run Code Online (Sandbox Code Playgroud)

这是我的组件定义:

class MyComponent extends HTMLElement {
  constructor() {
    super();
  }
  
  static get observedAttributes() {
    return ['foo'];
  }
  
  attributeChangedCallback(attrName, oldVal, newVal) {
    console.log('[my component] attribute', attrName, 'changed from', oldVal, 'to', newVal);
  }
}

window.customElements.define('my-component', MyComponent);

// Change value of the component attribute
$('#myBtn').click(() => $('#compo').attr('foo', 'baz'));
Run Code Online (Sandbox Code Playgroud)

在该页面上,当我单击按钮时,我在以下日志中有以下日志console.log

[我的组件] 属性 foo 从 bar 更改为 baz

[我的组件] 属性 foo 从 bar …

html javascript web-component custom-element

5
推荐指数
1
解决办法
1287
查看次数

在嵌套的 shadow DOM 中重新分配重复的槽元素

背景:这个问题与 Chrome 最新版本扩展的开发有关。它依赖于 javascript 功能,例如并非在所有浏览器上都可用的 HTML 导入和自定义元素,但在这种情况下是可以的。

我正在尝试实现一个简化的 HTML 自定义元素,如下所示:

<custom-el>
    <span slot="head">Great</span>

    <span slot="item">Item one</span>
    <span slot="item">Item two</span>

    <span slot="foot">done</span>
</custom-el>
Run Code Online (Sandbox Code Playgroud)

我注册了<custom-el>. 每次创建元素时,我的代码的自定义元素类都会附加一个影子根并附加到以下模板中的影子根内容:

<template id="main">
    <h1><slot name="head"></slot></h1>
    <ul>
        <slot name="item"></slot>
    </ul>
    <i><slot name="foot"></slot></i>
</template>
Run Code Online (Sandbox Code Playgroud)

我想将每个<span>属性重新分配slot="item"给负责呈现单个项目的辅助模板:

<template id="sub">
    <li><slot name="item"></slot></li>
</template>
Run Code Online (Sandbox Code Playgroud)

带属性的槽数name="item"不固定。它从数据库生成并定期更改。

我知道可以通过将 shadowRoot 附加到插槽的父元素并设置插槽的插槽属性来重新分配插槽,例如<slot name="item" slot="newItem">. 但我认为这在我的情况下不起作用,因为子模板需要包装每个项目实例,而不是项目列表。

我可以将影子根和子模板附加到主文档中的每个项目。这会起作用,但我的偏好是主模板导入并应用任何嵌套的 shadowRoots 和模板。这样,主文档只需要导入包含主模板的文件。组件细节的实现被封装在主模板html文件中。

我还可以使用slotchange事件和HTMLSlotElement.assignedNodes方法来拼凑脚本解决方案。但我宁愿不走那条路。

还有另一种方法吗?我的实际用例涉及更复杂的 HTML 结构。或者我的架构或对 Web 组件的理解有缺陷?

html web-component google-chrome-extension shadow-dom custom-element

5
推荐指数
1
解决办法
832
查看次数

在 shadow DOM 内部和外部使用非 shadow DOM 自定义元素

我有一个自定义元素(没有 shadow DOM),我希望能够在任何地方使用,甚至在另一个可能使用 shadow DOM 的自定义元素中。但是,我不确定如何让样式在这两个地方都有效。

例如,假设我创建了一个简单的fancy-button元素:

class fancyButton extends HTMLElement {
  constructor() {
    super();

    this.innerHTML = `
      <style>
      fancy-button button {
        padding: 10px 15px;
        background: rgb(62,118,194);
        color: white;
        border: none;
        border-radius: 4px
      }
      </style>
      <button>Click Me</button>`;
  }
}

customElements.define('fancy-button', fancyButton);
Run Code Online (Sandbox Code Playgroud)
<fancy-button></fancy-button>
Run Code Online (Sandbox Code Playgroud)

在 shadow DOM 元素内,插入的样式标签将允许fancy-button样式工作。但是,如果在 shadow DOM 元素之外使用此组件,则每次使用该元素时都会复制样式标记。

相反,如果我将样式标记添加为 html 导入文件的一部分,那么样式只能在 shadow DOM 之外工作,但至少它们只声明一次。

<!-- fancy-button.html -->
<style>
fancy-button button {
  padding: 10px 15px;
  background: rgb(62,118,194);
  color: white;
  border: none;
  border-radius: 4px
}
</style>

<script> …
Run Code Online (Sandbox Code Playgroud)

html web-component shadow-dom custom-element

5
推荐指数
1
解决办法
3100
查看次数

Web 组件渲染性能

与原生 HTML 元素相比,Web 组件是否提供更好的性能。因为每个元素只有在附加到 DOM 时才会发生变异。因此,元素回调中的昂贵操作会导致性能不佳。

我写了一个示例 Web 组件,在 connectedCallback 句柄中有一些昂贵的实现,当我尝试渲染组件时,每个组件都以连续的顺序花费时间。

我在 Web Components 上没有看到任何与参考相关的性能指标。


更新 1

我创建了一个带有 Native 和 Web Component 实现的小页面,似乎 Web Components 页面需要 4ms 才能完成,但 Native 只需要 1ms。请参阅我的性能屏幕。在 Web 组件中,脚本编写需要更多时间。

原生 HTML 示例:

本机示例


Web 组件示例:

在此处输入图片说明

html javascript web-component html-rendering web-performance

5
推荐指数
3
解决办法
5377
查看次数

如何使用 CSS 选择子类自定义元素

考虑以下:

class MyElem extends HTMLElement {};
customElements.define('my-element', MyElem);

class MyMoreSpecificElem extends MyElem {};
customElements.define('my-more-specific-element', MyMoreSpecificElem);
Run Code Online (Sandbox Code Playgroud)

在对象继承的说法中,第二个类的实例与第一个类具有“is-a”关系: aMyMoreSpecificElem 是 a MyElem

这种关系在 JavaScript 中被捕获:

let subclassInstance = document.querySelector('my-more-specific-element');
let parentClass = document.querySelector('my-element').constructor;

subclassInstance instanceof parentClass; // true
Run Code Online (Sandbox Code Playgroud)

但是我想不出任何MyElem使用 CSS 选择器选择所有s(包括子类 MyMoreSpecificElem)的方法。标签选择器只会获得超类或子类,我知道的所有关系描述选择器(例如~、>)都是关于文档中的位置,而不是类层次结构。

我的意思是,当然,我可以在构造函数中添加一个 CSS 类并通过它进行选择,调用super将确保甚至可以以这种方式选择子类实例。但这很粗糙。有没有办法在纯 CSS 中做到这一点?

javascript css subclassing web-component custom-element

5
推荐指数
1
解决办法
596
查看次数

将函数传递给模板组件

是否可以将函数传递给stencilJs组件?

就像是:

@Prop() okFunc: () => void;
Run Code Online (Sandbox Code Playgroud)

我有一个模态,想Ok在模态页脚中单击的按钮上动态调用传递的函数,就像onClick在普通 HTML 按钮上一样。

html function stencils web-component

5
推荐指数
2
解决办法
4560
查看次数