我刚刚遇到了一个有趣的情况,我<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但这不会做同样的事情,因为我的事件将不再是用户生成的,并且有大量与之相关的规则。
我有一个<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它基本上使用以下步骤延迟自定义元素初始化:
nextSibling(在这种情况下解析器可能已经通过my-el),或者是否DOMContentLoaded已经到达(又名document.readyState !== 'loading')。MutationObserver就childList重新检查以上条件。概述的策略目前仍然存在的问题是,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
嗨,我是 Web 组件概念的新手。我想知道我们是否可以使用 shadowRoot.querySelector 访问带槽的元素
我已经实现了一个输入字段作为用于动态设置一些值的插槽。并为其添加一个类“列标题”。我正在尝试像这样在 connectedCallback() 中访问这个元素
var titleInput = this.shadowRoot.querySelector('.column-title')
但它返回空值。
请帮忙。
我创建了两个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) 我正在创建一些 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?
看起来 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)
web-component css-import native-web-component material-design-icons
我是 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 文件夹中进行测试?
谢谢
我正在定义一个自定义元素
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 处理程序,但它不起作用。这很令人困惑
进一步的发现,当从原型中省略时,定义处理程序是有效的
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)
如果我们能得到对这种现象的解释,我会非常高兴。
如果有人遇到同样的问题,我想出了一个解决方法。可能值得注意的是,只有在实例化类的直接原型中定义的处理程序才会被附加,这对性能有好处,但可能有缺陷的逻辑。无论如何,它可以根据您的要求进行调整。
// Only in the base class …Run Code Online (Sandbox Code Playgroud) 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
我想测试我的自定义组件之一中插槽的内容。\n如果我在 html 文件中使用我的组件并在浏览器中打开它,一切都会按预期运行。但是,如果我想用玩笑来自动化测试,它就会失败。下面是一个输出形式为 jest 的最小工作示例:
\n占位符.js:
\nconst 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;\nRun Code Online (Sandbox Code Playgroud)\n占位符.test.js:
\nimport 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
javascript ×7
shadow-dom ×3
css-import ×1
dom ×1
ecmascript-6 ×1
html ×1
jestjs ×1
vue.js ×1
vuejs2 ×1