标签: native-web-component

我可以在 Shadow DOM 中获得一个按钮来提交不在 Shadow DOM 中的表单吗?

我刚刚遇到了一个有趣的情况,我<button>在放置在<form>.

  <form id="one" action="" method="get">
    <s-button>Select</s-button>
      #shadow-root
        <button>...</button>
    <button>Outside</button>
  </form>
Run Code Online (Sandbox Code Playgroud)

我也有一个<button>作为<form>.

孩子<button>导致表单提交。

但是<button>在 shadow-root 中没有。

在某种程度上,我想这是有道理的。但是有没有人想出一种方法来告诉 shadow-root<button>正常工作,<form>或者这是我必须通过 JS 处理的事情?

我知道单击事件在 Shadow DOM 层被阻止,但我很惊讶没有办法让按钮仍然是表单的一部分,可以通过属性或属性设置的东西。

当然,我可以捕获点击事件,然后从中发送一个新的事件,this但这不会做同样的事情,因为我的事件将不再是用户生成的,并且有大量与之相关的规则。

shadow-dom custom-element native-web-component

6
推荐指数
1
解决办法
1931
查看次数

当一个mutationObserver 触发一个带有单个元素的childList 更改时,假设该元素被完全解析是否安全?

我有一个<my-el>结构与此类似的自定义元素(纯静态的、服务器呈现的 HTML):

<my-el>
  <div>a</div>
  <div>b</div>
  <div>c</div>
  <div>d</div>
</my-el>
Run Code Online (Sandbox Code Playgroud)

由于 Chrome 不保证connectedCallback自定义元素的子元素可用性,我使用HTMLParsedElement它基本上使用以下步骤延迟自定义元素初始化:

  1. 测试元素(或任何祖先元素)是否具有nextSibling(在这种情况下解析器可能已经通过my-el),或者是否DOMContentLoaded已经到达(又名document.readyState !== 'loading')。
  2. 如果以上都不是,设置一个MutationObserverchildList重新检查以上条件。

概述的策略目前仍然存在的问题是,MutationObserver当这是可用的 HTML 时,可能会被触发:

<my-el>
  <div>a</div>
  <div>b</div>
</my-el>
Run Code Online (Sandbox Code Playgroud)

甚至这个

<my-el>
  <div>a</div>
</my-el>
Run Code Online (Sandbox Code Playgroud)

在这些情况下, MutationObserver 会被多次触发,并且处理程序无法知道</my-el>实际何时到达结束。

问题:有谁知道div像这样包装所有内部元素是否可以解决这个问题:

<my-el>
  <div>
    <div>a</div>
    <div>b</div>
    <div>c</div>
    <div>d</div>
  </div>
</my-el>
Run Code Online (Sandbox Code Playgroud)

或者换句话说,当变异观察者为这个结构触发时,我能否可靠地假设包装子 div 完全可用,包括它的所有后代节点?

javascript dom mutation-observers custom-element native-web-component

5
推荐指数
0
解决办法
258
查看次数

Web 组件:如何使用 shadowRoot.querySelector 访问带槽元素

嗨,我是 Web 组件概念的新手。我想知道我们是否可以使用 shadowRoot.querySelector 访问带槽的元素

我已经实现了一个输入字段作为用于动态设置一些值的插槽。并为其添加一个类“列标题”。我正在尝试像这样在 connectedCallback() 中访问这个元素

var titleInput = this.shadowRoot.querySelector('.column-title')

但它返回空值。

请帮忙。

javascript web-component native-web-component

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

如何指定运行嵌套Web组件构造函数的顺序?

我创建了两个Web组件,并将其中一个嵌套到另一个。他们两个都有constructor。我的问题是,我无法控制constructors 的序列。有什么办法可以解决这个问题?

这是我的代码:

子网络组件:

(function () {
    const template = document.createElement('template');
    template.innerHTML = `<div>WC1</div>`;

    class WC1Component extends HTMLElement {

        constructor() {
            super();
            console.log('WC1: constructor()');

            var me = this;

            me._shadowRoot = this.attachShadow({ 'mode': 'open' });
            me._shadowRoot.appendChild(template.content.cloneNode(true));
        }

        connectedCallback() {
            console.log('WC1: connectedCallback');
        }

        test() {
            console.log('test:wc1');
        }

    }

    window.customElements.define('wc-one', WC1Component);

}());
Run Code Online (Sandbox Code Playgroud)

父网络组件:

(function () {
    const template = document.createElement('template');
    template.innerHTML = `
    <wc-one id="wc1"></wc-one>
    <div>WC2</div>
    `;

    class WC2Component extends HTMLElement {

        constructor() {
            super();
            console.log('WC2: constructor()');

            var me …
Run Code Online (Sandbox Code Playgroud)

javascript web-component native-web-component

5
推荐指数
0
解决办法
60
查看次数

如何将自定义元素的文本内容分配给模板槽?

我正在创建一些 Web 组件并希望将包含的文本插入到模板槽中。我想让它可插入而不是简单地复制它们的值,以便浏览器可以自然地处理对文本的更改,而不必通过组件本身传递它。

根据 MDN textNodes是可插槽的,但是除了v1.x 中已弃用的元素之外,我找不到任何真正的方法来做到这一点。(textNodes 不支持属性,所以我不能简单地以这种方式为其分配一个插槽,并且 .assignedSlot() 是只读的。)文档之外的支持非常少,尽管这是一种新技术所期望的.

<my-element>some text</my-element>

<template>
 <h3><slot name="label"></slot></h3>
 <p>Derp</p>
</template>
Run Code Online (Sandbox Code Playgroud)

将此作为一个简化示例,我想出some text现在label插槽中,并在标记更改时相应地进行更新。有没有好的/集成的方法来做到这一点?我是否必须求助于mutationObserver?

javascript native-web-component

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

如何在 Web 组件中使用 Material Design 图标?

看起来 mdi 无法在 Web 组件内工作,或者我错过了什么?

我想开发一个封装其依赖项的 Web 组件,将链接添加到父文档是可行的,但它违反了初衷。

<html>
<body>
<x-webcomponent></x-webcomponent>
<script>
customElements.define(
  "x-webcomponent",
  class extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" });
      this.shadowRoot.innerHTML = `
        <style>@import url('https://cdn.materialdesignicons.com/4.9.95/css/materialdesignicons.min.css');</style>
        <span class="mdi mdi-home"></span>
      `;
    }
  }
);
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

https://codepen.io/Jamesgt/pen/MWwvJaw

web-component css-import native-web-component material-design-icons

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

如何使用 Vue CLI 一次性将多个 Vue.js 组件构建为原生 Web 组件?

我是 Vue.js 的新手,想使用它制作一个 Web 组件的 SDK。我可以像这样制作一个 Web 组件:

main.js:

import Vue from 'vue';
import App from './App.vue';
import wrap from '@vue/web-component-wrapper';

const customElement = wrap(Vue, App);

window.customElements.define('sky-chat', customElement);
Run Code Online (Sandbox Code Playgroud)

命令行命令:

vue build --target wc --name sky-chat ./src/main.js
Run Code Online (Sandbox Code Playgroud)

但这仅适用于一个组件。如何构建一堆 .vue 文件以一次性将 Web 组件分离到单独的 js 文件中?

如何自动生成一个测试 html,其中包含其中的所有组件,以便在构建后在 dist 文件夹中进行测试?

谢谢

javascript vue.js vue-component vuejs2 native-web-component

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

自定义元素未拾取 onclick

我正在定义一个自定义元素

customElements.define("my-button", class extends HTMLButtonElement {
  onclick() {
    console.log("bar");
  }
}, { extends: "button" })
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/tuxkjp3q/

但是当我点击它时什么也没有发生。

这是为什么?如何将事件处理程序附加到类的每个实例而不覆盖构造函数?

编辑:

当我检查 DOM 对象时,有一个 onclick 处理程序,但它不起作用。这很令人困惑

在此输入图像描述

编辑2:

进一步的发现,当从原型中省略时,定义处理程序是有效的

customElements.define("my-button", class extends HTMLButtonElement {
  constructor() {
    super();
    this.onclick = () => console.log("bar");
  }
}, { extends: "button" })
Run Code Online (Sandbox Code Playgroud)

但是当原型包含时onclick,相同的处理程序将不再起作用

customElements.define("my-button", class extends HTMLButtonElement {
  onclick() {
    console.log("bar");
  }

  constructor() {
    super();
    this.onclick = () => console.log("bar");
  }
}, { extends: "button" })
Run Code Online (Sandbox Code Playgroud)

如果我们能得到对这种现象的解释,我会非常高兴。

编辑3:

如果有人遇到同样的问题,我想出了一个解决方法。可能值得注意的是,只有在实例化类的直接原型中定义的处理程序才会被附加,这对性能有好处,但可能有缺陷的逻辑。无论如何,它可以根据您的要求进行调整。

// Only in the base class …
Run Code Online (Sandbox Code Playgroud)

html javascript ecmascript-6 native-web-component

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

关于 this.attachShadow({mode: 'open'}) 和 this.shadowRoot 的澄清

关于原生WebComponents

constructor()开头的方法中class,通常将影子 DOM 树附加到Custom Element并返回对其的引用ShadowRoot

class myCustomElement extends HTMLElement {

  constructor() {
    super();
    const shadowroot = this.attachShadow({mode: 'open'});
  }

 [... REST OF CODE HERE...]

}
Run Code Online (Sandbox Code Playgroud)

当然,引用的名称可以是任何名称。

我见过:

  • var shadow = this.attachShadow({mode: 'open'});(看:Element.attachShadow()
  • this.root = this.attachShadow({mode: 'open'});

我们可以很容易地使用:

  • const myShadowRootzzz = this.attachShadow({mode: 'open'});

然而,已经存在Element.shadowRoot作为参考ShadowRoot

那么为什么语法是

const shadow = this.attachShadow({mode: 'open'});
Run Code Online (Sandbox Code Playgroud)

在示例中经常使用,简单说明时:

this.attachShadow({mode: 'open'});
Run Code Online (Sandbox Code Playgroud)

就足够了,因为......任何时候ShadowRoot需要引用,该引用字面意思是:

this.shadowRoot 
Run Code Online (Sandbox Code Playgroud)

为什么 WebComponent …

web-component shadow-dom custom-element native-web-component

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

如何在 javascript 中使用 jest 测试 Web 组件中的开槽元素(无框架)

我想测试我的自定义组件之一中插槽的内容。\n如果我在 html 文件中使用我的组件并在浏览器中打开它,一切都会按预期运行。但是,如果我想用玩笑来自动化测试,它就会失败。下面是一个输出形式为 jest 的最小工作示例:

\n
\n

占位符.js:

\n
const template = document.createElement("template");\ntemplate.innerHTML = `\n    <p>\n        <slot></slot>\n    </p>\n`;\n\n\nclass Placeholder extends HTMLElement {\n    constructor() {\n        super();\n\n        this.attachShadow({ mode: "open" });\n        this.shadowRoot.appendChild(template.content.cloneNode(true));\n    }\n\n    get name() {\n        return this.shadowRoot.querySelector("slot").innerText;\n    }\n}\n\nwindow.customElements.define("place-holder", Placeholder);\n\nexport default Placeholder;\n
Run Code Online (Sandbox Code Playgroud)\n
\n

占位符.test.js:

\n
import Placeholder from "../src/placeholder.js";\n\ndescribe("name is 'Lorem Ipsum'", () => {\n    let ph;\n    \n    beforeAll(() => {\n        ph = new Placeholder();\n        const textNode = document.createTextNode("Lorem Ipsum");\n        ph.appendChild(textNode);\n    });\n\n    test("if the name is 'Lorem Ipsum'", () => {\n …
Run Code Online (Sandbox Code Playgroud)

javascript web-component shadow-dom jestjs native-web-component

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