提问人:Merc 提问时间:12/3/2015 最后编辑:SupersharpMerc 更新时间:11/3/2016 访问量:856
在 Web 组件中扩展元素时,“is”语法的意义何在?
What is the point of the "is" syntax when extending elements in web components?
问:
在 Web 组件中,要注册元素,只需键入:
var XFoo = document.registerElement('x-foo', {
prototype: Object.create(HTMLElement.prototype)
});
若要创建元素,可以执行下列操作之一:
<x-foo></x-foo>
var xFoo = new XFoo();
document.body.appendChild(xFoo);
var xFoo = document.createElement( 'x-foo')
document.body.appendChild(xFoo);
这一切都很好,花花公子。当您谈论扩展现有元素时,问题就开始了。
var XFooButton = document.registerElement('x-foo-button', {
prototype: Object.create(HTMLButtonElement.prototype),
extends: 'button'
});
问题 1:为什么要重复?在这里,应该就足够了(特别是因为它很容易计算出元素的原型'button'
Object.getPrototypeOf(document.createElement(tag));
问题 2:这些信息如何在内部使用?例如,如果您拥有 and(之后的内容与传递的原型不匹配),会发生什么情况prototype: Object.create(HTMLFormElement.prototype
extends: 'button'
extends
要创建一个,您可以执行下列操作之一:
<button is="x-foo-button"></button>
var xFooButton = new XFooButton();
document.body.appendChild(xFoo);
var xFooButton = document.createElement('button', 'x-foo-button');
document.body.appendChild(xFooButton);
问题 3:既然很明显扩展,为什么我们在使用时必须同时指定它们?我怀疑这是因为简单地创建了一个带有语法的标签,这让我想到了下一个问题:x-foo-button
button
document.createElement()
document.createElement()
<button is="x-foo-button"></button>
问题 4:语法的意义何在?这样做的实际区别是什么:is
var XFooButton = document.registerElement('x-foo-button', {
prototype: Object.create(HTMLButtonElement.prototype),
extends: 'button'
});
还有这个:
var XFooButton = document.registerElement('x-foo-button', {
prototype: Object.create(HTMLButtonElement.prototype),
});
除了 1) 第一种语法需要在文档中创建一个实例 2) 第二种语法可以用于任何元素,而不仅仅是自定义元素的扩展?<button is="x-foo-button"></button>
答:
答案 1明显的重复是因为您的示例非常简单。在真实的虚拟生活中,您将提供不同的原型。registerElement
带有自定义按钮的示例,单击该按钮时将显示一个弹出窗口:
//Custom method
function callback ()
{
console.log( this + " {created}" )
this.onclick = function ( event )
{
alert( this.id + " " + this.value )
}
}
//Type Extension
var newProto = Object.create( HTMLButtonElement.prototype )
newProto.createdCallback = callback
var XFooButtonExt = document.registerElement( 'x-foo-button', {
prototype: newProto,
extends: 'button'
} )
newProto
与 的 不同。HTMLButtonElement
prototype
使用以下 HTML 代码:
<button is="x-foo-button" id="Hello" value="World"> Hello </button>
单击它将在弹出窗口中显示“Hello World”。
答案 2这是一个语义指示,告诉浏览器提供的新原型实现了接口。这就是为什么从继承自 的对象开始更容易的原因。相反,您可以从原型开始,但您必须重新实现接口的所有属性和方法。extends: 'button'
HTMLButtonElement
HTMLButtonElement
HTMLFormElement
HTMLButtonElement
否则,元素行为将不正确。在上面的示例中,如果将一行替换为:
var newProto = Object.create( HTMLFormElement.prototype )
...单击它将失败,因为该属性未在元素中实现。value
<form>
该属性始终是正确的,因为它由接口提供,由每个元素(包括 )实现。id
HTMLElement
<form>
请注意,您可以添加缺少的属性,并将它们链接到方法中的属性。attributeChangedCallback
答案 3你是对的。这保持了与旧浏览器的向后兼容性,这些浏览器将忽略第二个参数,仍然能够创建一个普通元素(示例中的标准)。<button>
答案 4自定义元素范式背后有 2 个不同的概念:
- 如果要扩展标准 HTML 元素,请键入 Extensions (Customized Built-in Elements)。
- 自定义标签(自治自定义元素),如果要定义具有新名称的自定义元素。
两者都使用相同的方法定义。/ 选项允许您选择其中之一。registerElement
extends
is
该语法仅适用于类型扩展,因此始终与选项相关联。is
extends
使用类型扩展,可以保留扩展元素的所有语义:CSS 样式、内置行为(接口)、辅助功能。向后兼容性是此语法的另一个好处。
使用自定义标记时,您将失去语义,并且您的自定义元素应仅实现接口,而没有内置样式或行为。HTMLElement
更新:下一个示例(适用于 Chrome 和 Opera)说明了类型扩展和自定义标记之间的区别。
//Method
function callback() {
this.textContent = this //Get the HTML semantics
this.onclick = function(event) {
try {
var output = this.id + " "
output += this.name //works only with <button is=...>
}
catch (e) {
output += "a generic element"
}
alert(output)
}
}
//Type Extension
var newProto = Object.create(HTMLButtonElement.prototype)
newProto.createdCallback = callback
var XFooButtonExt = document.registerElement('x-foo-button', {
prototype: newProto,
extends: 'button'
})
//Custom Tag
var newProto2 = Object.create(HTMLButtonElement.prototype)
newProto2.createdCallback = callback
var XFooButtonCust = document.registerElement('x-foo-button-2', {
prototype: newProto2,
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Custom Elements</title>
</head>
<body>
<h3>Type Extension</h3>
<button is="x-foo-button" id="I'm" name="a button">Type Extension</button>
<h3>Custom Tag</h3>
<x-foo-button-2 id="I'm" name="a button">Custom Tag</x-foo-button-2>
</body>
</html>
评论
var XFooButton = document.registerElement('x-foo-button', { prototype: Object.create(HTMLButtonElement.prototype), });
HTMLButtonElement
value
name
<button>
user agent stylesheet
评论
<card-t cid='queen-of-cards'></card-t>
<img is=queen-of-hearts>