web-component 相关问题

Web组件是使用本机代码或第三方库创建的可重用客户端元素。

Web 组件中的拖放 API(Lit)

背景语境 我设法使用普通元素和事件侦听器学习了拖放 API 的基础知识。但我想看看是否可以使用 Web Compone 重新创建相同的功能...

回答 1 投票 0

Web 组件输入单选不在组中

我有WC 女巫是我的表单和输入字段的包装。 在 m-form 的 renderHTML() 中我这样做: 渲染 HTML() { this.loadChildComponents().then(children => { ...

回答 1 投票 0

是否可以在打字稿中为动态生成的类方法创建类型定义?

有没有办法为动态生成的类方法名称创建类型定义,并遵循 {name}Ref 等命名格式?基本上,我想知道这样的事情是否可能......

回答 1 投票 0

Shadow DOM 样式隔离

将 Shadow DOM 样式与 Main DOM 样式隔离似乎有些奇怪,请参见下文。 本质上,如果我对 tagName 很具体,那么就会存在隔离,但如果我使用 * 作为 CSS

回答 1 投票 0

点亮不渲染开槽子项

我想创建一个自定义元素来呈现选择输入。 一个父级创建 ,然后槽根据一系列选择生成 。 导入 {html, css, LitElement}... 我想创建一个自定义元素来呈现选择输入。 一个家长创建 <select>,然后 slot 根据一系列选择生成 <option>。 import {html, css, LitElement} from 'lit'; export class SimpleSelect extends LitElement { static properties = {}; constructor() { super(); } render() { return html`<select><slot><option>None</option></slot></select>`; } } customElements.define('simple-select', SimpleSelect); export class SimpleOptions extends LitElement { static properties = { options: {type: Array}, }; constructor() { super(); this.options = []; } render() { let opts = this.options.map((el) => `<option value="${el.value}">${el.label}</option>` ); return html`${opts.join("")}`; } } customElements.define('simple-options', SimpleOptions); <!DOCTYPE html> <head> <script type="module" src="./simple-greeting.js"></script> </head> <body> <simple-select> <simple-options options='[{"label":"A","value":"a"},{"label":"B","value":"b"},{"label":"C","value":"c"}]'></simple-options> </simple-select> </body> 这无法渲染已开槽的子项; 游乐场。 我不相信这就是 Lit Element 的设计用途。查看点亮的游乐场代码,您可以看到浏览器不会将组件呈现为选择对象中的选项,而是呈现两个自定义组件: 因为 LIT 元素使用 shadowDOMs,所以选择组件无法看到选项组件。 您可能可以使用查询选择器从简单选择中手动提取选项,但是,此时为什么不直接组合组件呢?这是组合组件的示例

回答 0 投票 0

如何从包含在 Shadow DOM 内的另一个 Web 组件定位到 Shadow DOM 内的元素

嗯,我不确定问题标题是否已经表达清楚......抱歉。 我想展示一个我已经在 DOM 上使用且没有问题的 wc-tooltip: 您可以使用 嗯,我不确定问题标题是否已经说清楚了……抱歉。 我想展示一个 wc-tooltip 我已经在 DOM 上使用而没有任何问题: <div> You can use <span class="disk-space" id="help">20GB</span> of space. <wc-tooltip target="help">It works only if you are a vampire.</wc-tooltip> </div> 我尝试在影子 DOM 的 Web 组件中使用它,但它不起作用: <Host> <span><slot/></span> { this.tip && <wc-icon id="help" name="my/fantastic/help/icon" /> <wc-tooltip target="help">{ this.tip }</wc-tooltip> } </Host> 这是因为我正在寻找 DOM 中的元素,而不是影子 DOM: componentDidRender (): void { const caller = document.getElementById(this.target) if (caller) { this.caller = caller this.caller.addEventListener('mouseleave', this.handleVisibility.bind(this, false)) this.caller.addEventListener('mouseenter', this.handleVisibility.bind(this, true)) return } console.error('Warning: property target is undefined.') } 显然,document.getElementById(this.target)无法工作。 问题是我没有弄清楚如何解决这个问题,我可以使用替代属性来指向shadow DOM元素,但是如何解决? IMO 设计的组件期望从组件外部访问它们的影子 DOM 内容(除了通过公共 API(如 @Methods))是不正确的设计。在这种情况下,我建议 wc-tooltip 应在插槽中包含 wc-icon,而不是成为同级组件(或创建一个单独的组件来包含两者),并且还保存工具提示显示逻辑。实际可见的“工具提示”只是影子 DOM 的一部分,而不是整个组件,它实际上只是图标(或其他任何东西)的包装器,用于侦听鼠标活动以显示/隐藏可见的工具提示。所以类似: <Host> <span><slot/></span> { this.tip && <wc-tooltip> <wc-icon slot="trigger" id="help" name="my/fantastic/help/icon" /> <div slot="tooltip">{ this.tip }</div> </wc-tooltip> } </Host> wc-工具提示: @State() tooltipVisible: boolean = false; @Listen('mouseenter') showTootlip() { this.tooltipVisible = true; } @Listen('mouseleave') hideTooltip() { this.tooltipVisible = false; } render() { return <Host> <slot name="trigger" /> <div style={{ display: this.tooltipVisible ? 'block' : 'none', position: 'absolute', left: ... }}> <slot name="tooltip" /> </div> </Host>; }

回答 1 投票 0

CSS :part 伪选择器可以用于设置嵌套 Web 组件的样式吗?

使用 Shadow DOM 创建具有封装样式的 Web 组件时,可以使用 ::part 伪选择器来设置部分阴影标记的样式(https://developer.mozilla.org/en-US/docs/Web/CSS/ ::

回答 2 投票 0

是否可以将 tailwind 类嵌入到 Shadow DOM 内隔离的 Svelte 自定义组件中?

我正在 Svelte 和 Tailwind 中构建自定义组件(Web 组件)。 我的目标是使这个组件具有独立的样式,但我在包含 Tailwind 样式表时遇到了麻烦...

回答 1 投票 0

Lit-Element:如何设置全局/重置 css

如果我使用 Lit-element,当前设置全局/重置 CSS 的最佳实践是什么? 我尝试过 1)将它们内联到我的文档根目录中的 中,2)像这个答案一样的构造样式表 ...</desc> <question vote="7"> <p>如果我使用 Lit-element,当前设置全局/重置 CSS 的最佳实践是什么? </p> <p>我尝试过1)将它们内联到我的文档根目录中的<pre><code>&lt;style&gt;</code></pre>中,2)像这样的构造样式表<a href="https://stackoverflow.com/questions/57325809/how-to-apply-global-css-to-web-components-through-shadow-dom">answer</a></p> <pre><code>&lt;script&gt; var css = new CSSStyleSheet() css.replace(&#39;@import url(&#34;./style/static/reset.css&#34;)&#39;) document.adoptedStyleSheets = [css] &lt;/script&gt; </code></pre> <p>但是没有任何效果...</p> <p><strong>编辑</strong> 我的<pre><code>reset.css</code></pre>:</p> <pre><code>blockquote, body, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, legend, p, pre, button, ul { margin: 0; padding: 0; } img { max-width: 100%; } </code></pre> <p>我正在构建于<a href="https://open-wc.org/guide/#quickstart" rel="noreferrer">https://open-wc.org/guide/#quickstart</a></p>的文件夹结构之上 </question> <answer tick="true" vote="8"> <p>这不会按您的预期工作,因为 LitElement 默认情况下使用 Shadow DOM,其设计目的是防止外部 CSS 影响组件的内部树(反之亦然)</p> <p>影响 Web 组件内部样式的唯一方法是组件是否使用 CSS 变量,或者继承样式的属性在 Web 组件内部未定义(有关更多信息,请检查<a href="https://lit-element.polymer-project.org/guide/styles#inheritance" rel="noreferrer">本指南</a>)</p> <p>但是,如果这是一个完全基于 LitElement 的项目,您可以非常轻松地在组件之间共享样式并使用它来执行此重置:</p> <ol> <li>首先为您的共享CSS创建一个js文件(例如reset-css.js)</li> </ol> <p></p><div data-babel="false" data-lang="js" data-hide="false" data-console="true"> <div> <pre><code>import { css } from &#39;lit-element&#39;; export default css ` blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, legend, p, pre, button, ul { margin: 0; padding: 0; } img { max-width: 100%; } `;</code></pre> </div> </div> <p></p> <ol start="2"> <li>然后在组件中导入您的样式</li> </ol> <p></p><div data-babel="false" data-lang="js" data-hide="false" data-console="true"> <div> <pre><code>import {LitElement, html, css} from &#39;lit-element&#39;; // include your reset styles import resetCSS from &#39;./reset-css.js&#39;; class MyComponent extends LitElement { static get styles() { // this is the important part, this array includes our resetted styles and this components styles return [ resetCSS, css` h1 { color: blue; } ` ]; } render() { html`&lt;h1&gt;Something Blue&lt;/h1&gt;` } }</code></pre> </div> </div> <p></p> <p>就像这样,任何包含共享重置样式的组件都将使用它们</p> </answer> <answer tick="false" vote="0"> <p>实现了一个实用程序类,因此您不必在组件中重新输入所有内容。</p> <pre><code>import { CSSResultGroup, LitElement } from &#34;lit&#34;; import { resetCSS } from &#34;../styles/reset.css.ts&#34;; import { customCss } from &#34;../styles/custom.css.ts&#34;; export abstract class Component extends LitElement { // Small hack to include global styles private static _styles: CSSResultGroup; static get styles(): CSSResultGroup { const derivedStyles = this._styles || []; return [ resetCSS, customCss, ...(Array.isArray(derivedStyles) ? derivedStyles : [derivedStyles]), ]; } static set styles(styles: CSSResultGroup) { this._styles = styles; } } </code></pre> <p>您现在可以按照习惯设置样式:</p> <pre><code>@customElement(&#34;app-root&#34;) export class MyElement extends Component { static styles = [ css` :host { max-width: 1280px; margin: 0 auto; padding: 2rem; text-align: center; } `, ]; //... </code></pre> </answer> </body></html>

回答 0 投票 0

shadow dom ::part 元素的样式子元素

我有一个 Web 组件,可以在 Shadow dom 中呈现以下内容: #shadow根 我就是标题文字! ...

回答 1 投票 0

在 Astro 中导入 StencilJs 生成的 Web 组件

我已经使用 StencilJs 构建了一个 Web 组件并将其发布到 NPM,并希望在 Astro 项目中使用它。 但是,网络组件未加载。 包.json: “混淆链接网络-com...

回答 1 投票 0

在多个地方使用相同的SVG图标时如何消除HTML代码重复?

我正在用普通的 JS、HTML 和 CSS 编写一个 HTML 页面。 到目前为止一切都很好,但我现在需要在四个不同的位置包含相同的 SVG 图标。 代码重复很糟糕,如果我...

回答 3 投票 0

如何访问Web组件上的observedAttributes

因此,在 Web 组件中,一旦您指定了要观察的属性,您就可以使用 attributeChangedCallback: 静态获取observedAttributes(){返回['myAttribute']; } 我如何列出/访问...

回答 1 投票 0

如何设置动态observedAttributes

我的目标是动态设置observedAttributes,因此我的Web组件将仅监视遵循某种模式的属性,例如冒号(:attr) 我的目标是动态设置 observedAttributes,因此我的 Web 组件将仅监视遵循某种模式的属性,例如冒号 (:attr) <my-element static="value1" :dynamic=${dynamic}/> 在这种情况下, <my-element> 应仅为属性 observedAttributes 设置 :dynamic 问题是 static get observedAttributes() 甚至在 this 之前运行,解释于 https://andyogo.github.io/custom-element-reactions-diagram/ 所以这行不通 static get observedAttributes() { return this.getAttributeNames().filter((item) => item.startsWith(':')); } 当然也没有 constructor() { super(); this._observedAttributes = this.getAttributeNames().filter((item) => item.startsWith(':')); } static get observedAttributes() { return this._observedAttributes; } 谢谢! <!DOCTYPE html> <body> <my-element static="value1" :dynamic="value2" ></my-element> <script> class MyElement extends HTMLElement { constructor() { super(); this._observedAttributes= this.getAttributeNames().filter((item) => item.startsWith(':')); console.log('observedAttributes',this._observedAttributes); } static get observedAttributes() { return this._observedAttributes; } attributeChangedCallback(name, oldValue, newValue) { console.log(name, oldValue, newValue); //doesn't log anything } } customElements.define("my-element", MyElement); setTimeout(() => { console.log('setting dynamic attribute. This should trigger attributeChangedCallback. But no.'); document.querySelector('my-element').setAttribute(':dynamic', 'value3'); }, 2000); </script> </body> </html> 您可以使用以下垫片来添加在元素的每个实例上动态观察属性变化的功能。您可以定义默认情况下在所有实例上观察到的属性,也可以在运行时添加仅在特定实例上观察到的属性。 class BaseClass extends HTMLElement { constructor({stat = BaseClass} = {}) { super() // console.log('constructor') this.#stat = stat this.#setAttribute = this.setAttribute this.setAttribute = function(name, value){ // console.log('attribute', name, this.observedAttributes, (this.observedAttributes.includes(name))) if (this.observedAttributes.includes(name)){ // do your stuff // console.log('attribute includes') this.attributeChangedCallback(name, this.getAttribute(name), value) } else { // do what you want } this.#setAttribute(name, value) } } #observedAttributes = [] get observedAttributes(){ return [...this.#stat.observedAttributes, ...this.#observedAttributes] } #setAttribute = null #stat = null addObservedProp(name){ this.#observedAttributes.push(name) } connectedCallback() {} disconnectedCallback() {} attributeChangedCallback(name, oldValue, newValue) { console.log('change', name, oldValue, newValue) } adoptedCallback() {} static get observedAttributes() { return ['a', 'b', 'c'] } } window.customElements.define('base-com', BaseClass) const test = document.getElementById('test') test.setAttribute('d', 'status 1') test.addObservedProp('d') test.setAttribute('d', 'status 2') console.log(test) <base-com id="test">Base com</base-com> 按照 @Danny '365CSI' Engelman 的建议,我查看了 MutationObserver API 并提出了一个简单的解决方案,我认为它提供的不仅仅是 observedAttributes <my-element static="value1" :dynamic="value2"></my-element> <script> class MyElement extends HTMLElement { constructor() { super(); } mutationObserverCallback(mutationList, observer) { for (const mutation of mutationList) { if (mutation.type === 'attributes' && mutation.attributeName.startsWith(':') && mutation.oldValue !== mutation.target.getAttribute(mutation.attributeName)) { console.log(`The dynamic ${mutation.attributeName} attribute was modified.`); } } } connectedCallback() { this.mutationObserver = new MutationObserver(this.mutationObserverCallback); this.mutationObserver.observe(this, { attributes: true, attributeOldValue: true }); } disconnectedCallback() { this.mutationObserver.disconnect(); } } customElements.define("my-element", MyElement); setTimeout(() => { console.log('setting dynamic attribute for :dynamic and static attributes. This should trigger mutationObserverCallback for :dynamic only.'); // ▼ will trigger mutationObserverCallback document.querySelector('my-element').setAttribute(':dynamic', 'value3'); // ▼ will not trigger mutationObserverCallback document.querySelector('my-element').setAttribute('static', 'value4'); }, 200); </script>

回答 2 投票 0

ViewEncapsulation.Emulated 样式由 ViewEncapsulation.(Native|ShadowDom) 组件复制到 #shadow-root 中

我有一个示例存储库 https://github.com/collinstevens/angular-encapsulation 它演示了我的问题。 共有三个组件:EmulatedComponent、NativeComponent 和 ShadowDomCompo...

回答 3 投票 0

向 Docusaurus 添加自定义组件

我有一个相当大的角度组件导出为自定义组件,我想将其作为演示加载到我的 docusaurus 文档中它由几个捆绑包和其他资源组成,全部保存在

回答 1 投票 0

如何使用parcel在react中添加图片?

我一直在尝试在反应中添加图像。我没有使用webpack,我使用parceljs。我也尝试过使用打字稿: 从 path/to/image.png 导入图像 里面有反应

回答 4 投票 0

为什么在 Shadow DOM 中像 `:where(:root, :host) { --my-var: value }` 这样定义的 CSS 变量不起作用?

我注意到我在 Web 组件(使用 Shadow DOM)中定义的一些 CSS 变量没有按预期运行。看来使用 :where(:root, :host) 导致了该问题。 W...

回答 1 投票 0

Angular Web 组件 -> *ngIf 指令错误

我是 webComponents 的新手。我遇到了一个问题,请问你能帮助我吗? 让我告诉你到目前为止我做了什么: 我使用命令创建了一个类似 Angular shell 的项目 - ng 新的 MyAngularAppHold...

回答 1 投票 0

如何通过shadow DOM访问light DOM中slot内的特定html标签?

我创建了一个自定义元素并在 html 中定义它,如下所示: ` &... 我创建了一个自定义元素并在 html 中定义它,如下所示: ` <header> <custom-navbar links="[{title:'home'},{title:'About'}]" class="bg-purple"> <h1 slot="logo"> Amazon </h1> <navbar slot="link" class="navbar-wrapper"> <ul class="link-container"> </ul> </navbar> </custom-navbar> </header> ` 我定义了我的自定义元素,如下所示: class CustomNavbar extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); this.shadowRoot.innerHTML = ` <style> :host(.bg-purple){ display:flex; width:100%; background-color:purple !important; } .container{ display:flex; flex-direction:row; margin:1rem; align-items:center; } </style> <div class='container'> <div> <slot name="logo"></slot> </div> <slot name='link'></slot> </div> `; } connectedCallback() { this._links = this.getAttribute("links"); } } customElements.define("custom-navbar", CustomNavbar); 我正在寻找在 Shadow DOM 中获取 light DOM 中定义的 links 属性并将链接添加到 ul 元素?我还在 document.querySelector("custom-navbar").querySelector("ul") 内部使用了 :connectedCallback(),但它无法正常工作。 尝试此代码,它通过使用自定义元素的 HTML 中提供的 links 属性在影子 DOM 中动态创建并填充链接列表。 class CustomNavbar extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); this.shadowRoot.innerHTML = ` <style>:host(.bg-purple){display:flex;width:100%;background-color:purple!important;}.container{display:flex;flex-direction:row;margin:1rem;align-items:center;}</style> <div class='container'><div><slot name="logo"></slot></div><slot name='link'></slot></div> `; } connectedCallback() { const links = JSON.parse(this.getAttribute("links") || '[]'); const ulElement = this.shadowRoot.querySelector("ul.link-container"); links.forEach(linkInfo => { const liElement = document.createElement("li"); liElement.textContent = linkInfo.title; ulElement.appendChild(liElement); }); } } customElements.define("custom-navbar", CustomNavbar); 希望它有效:) connectedCallback 在 opening 标签上触发;所以现阶段还没有 解析的 lightDOM (除非CE是在DOM解析之后定义的) 所以你要么: 在 setTimeout 中使用 connectedCallback 来推迟在 lightDOM 中查询 <ul> 标签 在组件上添加一个 insertLI 方法来检查/等待 <ul> 存在 setTimeout是完全有效的,除非你有一个非常大的lightDOM(比如> 750个DOM节点)然后添加HTML解析元素代码 注: super(); this.attachShadow({ mode: "open" }); this.shadowRoot.innerHTML = `...` 可以链接到: super() // sets AND returns 'this' scope .attachShadow({ mode: "open" }) // sets AND returns this.shadowRoot .innerHTML = `...`

回答 2 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.