我创建了一个名为"memory-box"的自定义元素,如下面的代码所示.
请注意"memory-box-template"中的"logthis"功能.
内存box.html
<template id="memory-box-template">
<input id="memory-box" type="form" />
<input type="button" id="testbutton" />
<script type="text/javascript">
function logthis(me){
console.log(me);
}
</script>
</template>
<script type="text/javascript">
(function() {
var thisDoc = document.currentScript.ownerDocument;
var storage = localStorage;
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var temp = thisDoc.querySelector('#memory-box-template');
var con = document.importNode(temp.content, true);
this.createShadowRoot().appendChild(con);
var input = this.querySelector('::shadow #memory-box');
var data = storage.getItem(this.id);
input.value = data;
input.addEventListener('input', saveData.bind(input, this.id));
}
},
});
document.registerElement('memory-box', {
prototype: proto
});
function saveData(id, e) { …Run Code Online (Sandbox Code Playgroud) 如果我想在EcmaScript中动态创建新类(而不是实例),我该怎么做?那些extend来自另一个班级的实例怎么样?
传统上,人们可以成为"阶级":
function Living(){}
Living.prototype.eat = function(){ console.log("eat") }
Run Code Online (Sandbox Code Playgroud)
然后动态扩展它:
function makeSubclass(name, parentClass){
var klass = new Function()
klass.name = name
klass.displayName = name
klass.prototype = parentClass.prototype
klass.prototype.constructor = klass
}
var Animal = makeSubclass("Animal", Living)
var dog = new Animal()
dog.eat() //=> eat
Run Code Online (Sandbox Code Playgroud)
等等:
Animal.prototype.walk = function(){ console.log("one foot then another") }
var Person = makeSubclass("Person", Animal)
var rektide = new Person()
rektide.eat() //=> eat
rektide.walk() //=> one foot then another
Run Code Online (Sandbox Code Playgroud)
关键是我希望以数据驱动的方式动态地这样做.这种传统方法让我动态创建新类:
fetch("http://yoyodyne.net/animals").then(response …Run Code Online (Sandbox Code Playgroud) 我是网络组件的新手.我检查了一些例子,但我真的无法弄清楚如何加载(插入DOM)一个单独的Web组件的内容.从这个例子开始,我把这段代码放在一个名为my-element.html的文件中:
<template id="my-element">
<p>Yes, it works!</p>
</template>
<script>
document.registerElement('my-element', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'});
const t = document.querySelector('#my-element');
const instance = t.content.cloneNode(true);
shadowRoot.appendChild(instance);
}
});
</script>
Run Code Online (Sandbox Code Playgroud)
这是我的index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>my titile</title>
<link rel="import" href="my-element.html">
</head>
<body>
Does it work?
<my-element></my-element>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我在使用最新的Chrome 56,所以我不需要填充.我运行polyserve,只有"它有效吗?" 出现.我尝试(像原始示例)"customElements.define"语法而不是"document.registerElement",但不起作用.你有什么想法吗?如果我不想使用影子dom,我还能改变什么?
谢谢
javascript web-component html5-template custom-element html-imports
我正在尝试使用 shadow DOM 修改两个自定义 HTML 元素“输出屏幕”和“自定义计算器”的样式。
当我尝试通过附加如下所示的 shadow DOM 来执行此操作时,未应用样式。任何想法我做错了什么?
<custom-calculator id="calculator">
<output-screen></output-screen>
</custom-calculator>
<script>
var o = Object.create(HTMLElement.prototype);
var oElement = document.registerElement('output-screen', {
prototype: o
});
var c = Object.create(HTMLElement.prototype);
var cElement = document.registerElement('custom-calculator', {
prototype: c
});
var calc = document.querySelector('#calculator')
calc.attachShadow({ mode: 'open' });
calc.shadowRoot;
calc.shadowRoot.innerHTML = `
<style>
output-screen{
display:inline-block;
background-color:orange;
width:50%;
height:100vh;
}
custom-calculator {
display:inline-block;
background-color:grey;
width:100%;
height:100vh;
vertical-align:top;
}
</style>
`;
</script>
Run Code Online (Sandbox Code Playgroud) 鉴于我有一个要导出并用作独立的angular-element-component的组件。
export class CompanyFormComponent implements OnInit {
@Input() public companyId: string;
company: Company;
companyForm: FormGroup;
constructor(
private companyService: CompanyService,
private fb: FormBuilder,
) { }
ngOnInit() {
if (!this.companyId || this.companyId.length === 0) {
console.log('Please provide an Id');
}
Run Code Online (Sandbox Code Playgroud)
....
AppModule:
export class AppModule {
constructor(private injector: Injector) {}
ngDoBootstrap() {
const strategyFactory = new ElementZoneStrategyFactory(CompanyFormComponent, this.injector);
const element = createCustomElement(CompanyFormComponent, { injector: this.injector, strategyFactory });
customElements.define('app-company-form', element);
}
}
Run Code Online (Sandbox Code Playgroud)
Index.html:
<app-company-form></app-company-form>
Run Code Online (Sandbox Code Playgroud)
我希望能够在使用此组件的任何地方注入任何值,例如:
<app-company-form companyId=11></app-company-form>
Run Code Online (Sandbox Code Playgroud)
因此,可以从Angular之外的其他地方填充companyId。我不想对angular中的值进行硬编码。
我已经尝试了一些方法,但是似乎没有任何效果。
是否可以创建一个自定义元素,例如:“”,并且这个新元素将具有 iframe 元素的所有功能?(它自己的文档/窗口对象等等......)?
我确定我在规范中缺少一些基本知识,但是在Safari上运行的Mac上构建了大量自定义元素后,我发现它们在Firefox和Chrome上不起作用。我想念什么?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>NoCE</title>
<script>
class NoCE extends HTMLElement {
constructor(args) {
super();
}
connectedCallback() {
this.innerHTML = "<p>It Works</p>";
}
attributeChangedCallback(name, oldValue, newValue, namespaceURI) {}
disconnectedCallback() {}
adoptedCallback() {}
static get observedAttributes() { return []; }
}
customElements.define("no-ce", NoCE, { extends: "div" });
</script>
</head>
<body>
<no-ce>
No custom elements
</no-ce>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
在Safari中,页面显示“有效”。在Firefox和Chrome中,它显示“无自定义元素”(在Mac OS X上运行)。
Safari 12.0.2 Firefox 64.0.2 Chrome 71.0.3578.98
javascript firefox google-chrome web-component custom-element
我正在为我的 Web 组件实现 Orchestrator 模式,如下所示:
<body>
<my-controller>
<div>
<my-list>
<span>
<my-item></my-item>
</span>
</my-list>
</div>
</my-controller>
</body>
Run Code Online (Sandbox Code Playgroud)
我创建的所有自定义元素都使用 Shadow DOM 使用const root = super.attachShadow({mode: "open"}); root.appendChild(...);.
从我的内部 Web 组件中,我想在以下位置访问我的my-controller组件connectedCallback():
public connectedCallback(): void
{
if (this.isConnected)
{
for (let node = this.parentElement; node; node = node.parentElement)
if (node instanceof ContainerBase)
{
this._service = (<ContainerBase>node).GetService(this);
break;
}
if (this._service) this.Reset();
else throw new ReferenceError(`${this.nodeName.toLowerCase()}: Couldn't find host element while connecting to document.`);
}
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是:我只能访问直接父网络控件。
所以,如果connectedCallback() …
javascript google-chrome web-component shadow-dom custom-element
考虑以下基本自定义元素:
class XElement extends HTMLElement {
constructor() { super(); }
foo() { console.log( this ); }
} customElements.define( 'x-element', XElement );
Run Code Online (Sandbox Code Playgroud)
这是问题所在:
const xelem = new XElement();
/* `foo` will lose its binding to `xelem`:
*/ someButton.onclick = xelem.foo;
// These will work, but it's too verbose:
someButton.onclick = () => xelem.foo();
someButton.onclick = xelem.foo.bind( xelem );
Run Code Online (Sandbox Code Playgroud)
我看到只有一种解决方案是foo在构造函数中添加为箭头函数,但是在我看来这是错误的。
constructor() {
super();
this.foo = () => console.log( this );
}
Run Code Online (Sandbox Code Playgroud)
有没有正确的方法来创建永远不会失去其绑定的方法?
是否可以实例化Web组件而无需将其注册到 CustomElementRegistry?考虑一个简单的组件:
export class MyCustomElm extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.shadowRoot!.innerHTML = `
<div>Hello world</div>
`;
}
}
// Is it really required?
customElements.define('my-custom-elm', MyCustomElm);
Run Code Online (Sandbox Code Playgroud)
我正在使用故事书来构建Web组件库。所有示例/演示都是Web组件。该代码将始终使用构造函数语法,即new MyCustomElm()初始化组件。永远不会通过纯HTML使用它。
我试图不注册该元素,但它似乎不起作用。如果在不注册组件的情况下调用了构造函数,则会引发异常。由于演示组件很多,因此想出唯一的名称很快变得很麻烦。
或者,是否有任何方法可以将Storybook用于Web组件,而不必为故事设置额外的Web组件? (我尝试了DOM操作,但它也一发不可收拾。)
custom-element ×10
javascript ×9
shadow-dom ×3
angular ×1
class ×1
css ×1
dynamic ×1
element ×1
firefox ×1
html ×1
html-imports ×1
this ×1
typescript ×1