【问题标题】:Web Components : extending native elementsWeb 组件:扩展原生元素
【发布时间】:2019-10-30 07:43:55
【问题描述】:

我正在尝试创建一个扩展 div 元素的 Web 组件,我发现 this other Stack Overflow question 关于如何扩展本机元素(本例中为按钮)。但是,我不能让它工作。而且,根据this answer 中的更新,它应该可以工作。

如果您查看此简化代码 sn-p 中的结果,它只是呈现为带有文本的简单内联元素。 如果您打开 Chrome 控制台并查看属性选项卡,很明显它不会从 HTMLButtonElement 继承(它应该继承)。怎么了?

class FancyButton extends HTMLButtonElement {
    constructor() {
        super(); // always call super() first in the ctor.
        this.addEventListener('click', e => this.innerHTML = "I was clicked");
    }
}

customElements.define('fancy-button', FancyButton, { extends: 'button' });
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>title</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>
  <body>
    <fancy-button>Click me</fancy-button>
  </body>
</html>

【问题讨论】:

  • 试试&lt;button is='fancy-button'&gt;Test&lt;/button&gt;
  • 谢谢它的工作。

标签: javascript web-component


【解决方案1】:

自问自答

自定义元素有两种类型MDN: Using Custom Elements

  • 自主自定义元素
  • 自定义内置元素
    Safari 需要Polyfill
    因为 Apple...嗯.. 是 Apple.. 并且拒绝实施自定义元素

一个注册表来统治所有这些

只有一个注册表,因此您的自定义元素注册为fancy-button
可以NOT*自主表示法: &lt;fancy-button&gt;&lt;/fancy-button/&gt;

* Firefox DOES allow a mix of both notations BUT only if define() is used AFTER element usage


来自文档部分:扩展原生 HTML 元素:

https://developers.google.com/web/fundamentals/web-components/customelements#extendhtml

自定义内置元素的使用者可以通过多种方式使用它。
他们可以通过在原生标签上添加 is="" 属性来声明它:

    <!-- This <button> is a fancy button. -->
    <button is="fancy-button" disabled>Fancy button!</button>

在 JavaScript 中创建一个实例:

    // Custom elements overload createElement() to support the is="" attribute.
    let button = document.createElement('button', {is: 'fancy-button'});
    button.textContent = 'Fancy button!';
    button.disabled = true;

    // have to do this yourself!! IF you want to use it as a selector
    button.setAttribute("is","fancy-button");

    document.body.appendChild(button);

或使用 new 运算符:

    let button = new FancyButton();
    button.textContent = 'Fancy button!';
    button.disabled = true;

结论

自定义元素有2种,不能混用

你要么选择:

  • 自治自定义元素:&lt;fancy-button&gt;&lt;/fancy-button&gt;

  • 自定义内置元素&lt;button is=fancy-button&gt;&lt;/button&gt;

用于定制的内置元素

document.createElement('fancy-button') instanceof HTMLButtonElement

返回 false

&lt;fancy-button&gt;lightDOM&lt;/fancy-button&gt;

document.querySelector('fancy-button')

返回元素(如果在 DOM 中),
但该元素被处理为显示 lightDOM 内容的未定义元素


使用两种自定义元素的示例

https://cardmeister.github.io 中我都使用了:

&lt;card-t rank=queen suit=hearts&gt;&lt;/card-t&gt;

&lt;img is=queen-of-hearts/&gt;

因此我可以这样做:

&lt;queen-of-hearts&gt;&lt;/queen-of-hearts&gt;

后者价值不大,IMG 的is 属性可用于CSS 定位。
CSS Selector for a partial CustomElement nodename

【讨论】:

  • 很想听听你的推理。 is= 符号使我的其他项目变得非常容易。单个自闭合 DOM 元素:&lt;img is=white-king/&gt; , &lt;img is=black-king/&gt; ... etc
  • 很好的解释。 Internet Explorer中兼容性html“is”属性的任何解决方案?
  • 对不起,不要再做IE了。该帖子是一年前的……目前我对is(自定义内置元素)没有认真使用。苹果仍然拒绝实施它们。所以我只使用自治元素。
  • 我学到了is 的一件事。在 createElement 自定义 DOM 元素之后,如果您想将其用作选择器,则必须自己执行 button.setAttribute("is","fancy-button")。已将其添加到上面的代码中。我猜是因为元素已经创建为fancy-button,而is not 是observedAttribute。您不能将一个元素更改为另一个元素。
  • 非常感谢您抽出宝贵时间,您让我看得更清楚。我想我终于要另辟蹊径了
猜你喜欢
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 2012-12-09
  • 2016-10-23
相关资源
最近更新 更多