标签: native-web-component

如何在连接所有子自定义元素时使用'connectedCallback'

我正在使用Web Components v1.

假设有两个自定义元素:

家长element.html

<template id="parent-element">
    <child-element></child-element>
</template>
Run Code Online (Sandbox Code Playgroud)

儿童element.html

<template id="child-element">
<!-- some markup here -->
</template>
Run Code Online (Sandbox Code Playgroud)

我试图在连接时使用connectedCallbackin parent-element初始化整个父/子DOM结构,这需要与定义的方法进行交互child-element.

但是,似乎child-element没有正确定义当时connectedCallback被解雇customElement:

家长element.js

class parent_element extends HTMLElement {
    connectedCallback() {
        //shadow root created from template in constructor previously
        var el = this.shadow_root.querySelector("child-element");
        el.my_method();
    }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为它el是一个HTMLElement而不是child-element预期的.

parent-element的模板中的所有子自定义元素都已正确附加后,我需要回调.

这个问题的解决方案似乎不起作用; this.parentElementnull里面child-element connectedCallback().

ilmiont

html javascript web-component native-web-component

15
推荐指数
3
解决办法
1562
查看次数

CSS:如何在 Shadow DOM 根中定位 ::slotted 兄弟姐妹?

我知道规范目前只允许 ::slotted 的复合选择器,即::slotted(my-first + my-second)不允许,但这样的事情应该工作吗?

::slotted(x-first) + ::slotted(x-second) { /* css */ }
Run Code Online (Sandbox Code Playgroud)

有什么方法可以定位开槽的兄弟姐妹(除了使用全局 css)?如果没有,我会在哪里提交这样的请求?谢谢。

css web-component shadow-dom native-web-component

13
推荐指数
2
解决办法
7533
查看次数

我可以将函数作为属性传递给Web组件吗?

我正在尝试为input元素创建一个本机Web组件.我希望该组件具有自定义验证功能,类似于聚合物的纸张输入自定义验证器功能.我不确定我是否可以将自定义验证器函数作为属性传递给(web组件)输入元素的实例.任何建议,将不胜感激.

web-component custom-element native-web-component

8
推荐指数
2
解决办法
2565
查看次数

插槽无法在没有 Shadow dom 的 html Web 组件上工作

我有一个没有shadow dom 的html web 组件,我尝试添加一个插槽。由于某种原因它不起作用。

我希望它将“Foo bar”切换为“Hello world”,但这并没有发生。

  1. slot 只适用于 Shadow dom 和模板吗?
  2. 我怎样才能让它发挥作用?

class HelloWorld extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    this.innerHTML = `
      <div>
        <slot name="element-name">Foo Bar</slot>
      </div>
    `;
  }
}

customElements.define("hello-world", HelloWorld);
Run Code Online (Sandbox Code Playgroud)
<hello-world>
  <span slot="element-name">Hello World</span>
</hello-world>
Run Code Online (Sandbox Code Playgroud)

javascript components slots native-web-component

8
推荐指数
1
解决办法
3835
查看次数

自定义元素 getRootNode.closest() 函数跨越多个(父)shadowDOM 边界

我花了一些时间进行搜索,但只看到太多常规的“遍历 DOM”博客或仅提升一个级别的答案getRootnode()

伪代码:

HTML

<element-x>
//# shadow-root
    <element-y>
        <element-z>
        //# shadow-root
        let container = this.closest('element-x');
        </element-z>
    </element-y>
</element-x>
Run Code Online (Sandbox Code Playgroud)

标准element.closest()功能并没有捅破阴影边界;

所以this.closest('element-x')返回null因为没有 <element-x><element-z>shadowDom

目标:

<element-x>从后代内部查找<element z>(任何嵌套级别)

必需的:

A(递归).closest()函数,走了(阴影)DOM小号和认定<element-x>

注意:元素可能有也可能没有 ShadowDOM(参见<element y>:仅 lightDOM)

我可以而且明天会自己做;只是想知道是否有聪明的头脑已经做到了。

资源:

更新

这是以下答案中的未缩小代码:

        closestElement(selector, base = this) {
            function __closestFrom(el) {
                if (!el || el === document || el === window) return …
Run Code Online (Sandbox Code Playgroud)

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

7
推荐指数
3
解决办法
1816
查看次数

如何使用本机 Web 组件阻止 FOUC 发生

我正在尝试原生 Web 组件,到目前为止我真的很喜欢它们。

我创建了一个微型网站,其中包含主页、关于页面、联系页面以及通过更改 URL 的哈希部分来工作的菜单。

但是,我注意到一种不良效果 - 每当我从一个“页面”切换到另一个“页面”时(实际上,只是卸载一个本机 Web 组件,然后安装另一个),大约半秒钟,我就会看到 Web 组件渲染使用默认样式,然后使用我包含在影子 DOM 中的样式进行绘制。

最初,我的组件是这样的:

    const template = document.createElement('template');
    template.innerHTML = `
        <style>
            @import '../reset.css';
            @import '../vars.css';
            @import '../bodyText.css';
        </style>
        <div class="body-text">
            <h1>Home page</h1>
            <p>Home. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate …
Run Code Online (Sandbox Code Playgroud)

fouc native-web-component

7
推荐指数
2
解决办法
2714
查看次数

覆盖Web组件中的外部定义的样式

我正在迈入Web组件的第一步,而未使用任何第三方库(例如Polymer)。主要卖点之一是Web组件样式与其他地方定义的样式分开,从而允许在类似于沙盒的环境中对组件的shadow-DOM进行样式设置。

我遇到的问题是样式如何通过插槽元素级联。由于带槽的元素不是影子DOM的一部分,因此只能用::slotted()组件模板中的选择器对其进行定位。这很棒,但是几乎不可能保证Web组件在所有上下文中都能正确显示,因为外部定义的样式还具有无可比拟的专一性*应用于空位元素。

*此外!important

这个问题可以归结为:

customElements.define("my-nav",
  class extends HTMLElement {
    constructor() {
      super();

      const template = document.querySelector("template#my-nav").content;
      this.attachShadow({ mode: "open" })
        .appendChild(template.cloneNode(true));
    }
  }
);
Run Code Online (Sandbox Code Playgroud)
a {
  color: red; /*  >:(  */
}
Run Code Online (Sandbox Code Playgroud)
<template id="my-nav">
  <style>
    .links-container ::slotted(a) {
      color: lime;
      font-weight: bold;
      margin-right: 20px;
    }
  </style>

  <div class="links-container">
    <slot name="links"></slot>
  </div>
</template>

<p>I want these links to be green:</p>
<my-nav>
  <a href="#" slot="links">Link 1</a>
  <a href="#" slot="links">Link 2</a>
  <a href="#" slot="links">Link 3</a>
</my-nav> …
Run Code Online (Sandbox Code Playgroud)

javascript html5 web-component shadow-dom native-web-component

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

我可以在 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
查看次数

使用本机 Web 组件时,Typescript 错误“类型 'JSX.IntrinsicElements' 上不存在属性”

我正在处理一个使用 React 和 Typescript 的项目,但我想开始在我的项目中使用原生 Web 组件来逐步淘汰我的一些 React 组件。

当我尝试在我的person-info某些 JSX 中包含使用组件时出现此错误。

Property does not exist on type 'JSX.IntrinsicElements'
Run Code Online (Sandbox Code Playgroud)

我查看了其他一些有这些问题的问题,但它们似乎都与本机 Web 组件没有任何关系。

当我在我的项目中使用我的 web 组件时,如何让 Typescript 和 React 很好地发挥作用?

人物信息.mjs

const css = `
  <style>
    :host([hidden]) { display: none; }
    :host {
      align-items: center;
      display: grid;
      font-weight: normal;
      grid-gap: var(--spacing-size-a) var(--spacing-size-a);
      grid-template-areas:
        'picture heading'
        'picture sub-heading';
      grid-template-columns: auto 1fr;
      justify-items: start;
    }
    div {
      grid-area: picture;
    }
    h1, h2 {
      margin: 0;
      padding: 0;
    }
    h1 {
      align-self: …
Run Code Online (Sandbox Code Playgroud)

javascript web-component typescript reactjs native-web-component

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

动态实例化 Web 组件的方法之间的差异

Web 组件(仅针对此问题的自主自定义元素)可以通过多种方式“实现”。

以下三个选项之间是否存在显着差异?

选项1:

const foo = document.createElement('foo-element');
document.body.appendChild(foo);
Run Code Online (Sandbox Code Playgroud)

选项 2:

const div = document.createElement('div');
div.innerHTML = '<foo-element></foo-element>'
const foo = div.firstElementChild;
document.body.appendChild(foo);
Run Code Online (Sandbox Code Playgroud)

选项 3:

const foo = new FooElement;
document.body.appendChild(foo);
Run Code Online (Sandbox Code Playgroud)

我基于 Karma/Mocha 堆栈编写了一些单元测试,并使用选项 3 创建了我的实例。

这是否足够,也就是说,我可以使用任一方法依赖具有相同状态/行为的组件,还是有必要使用所有不同的实例化选项重复我的所有测试?

document.createElement由于错误,我的 Web 组件之一无法使用实例化:

VM977:1 Uncaught DOMException: Failed to construct 'CustomElement':
The result must not have attributes
at <anonymous>:1:10
Run Code Online (Sandbox Code Playgroud)

可以毫无问题地实例化相同的组件这一事实new告诉我,在幕后,必须存在显着差异,尤其是new FooElement和之间document.createElement('foo-element')

我可以编写三个通用测试来测试所有三种实例化方式,当然,但这足够了吗?

或者我所有现有的测试都应该使用所有 3 个实例化选项运行?

或者换个方式问:

实例化后每个实例是否完全相同?(假设没有错误)

javascript web-component custom-element native-web-component

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