"是什么意思?"扩展Web组件中的元素时的语法?

时间:2015-12-03 00:04:55

标签: javascript web-component custom-element

在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 :该信息如何在内部使用?例如,如果你有prototype: Object.create(HTMLFormElement.prototypeextends: 'button'extends之后&#39}与原型传递不匹配会怎样?

要创建一个,您可以执行以下操作之一:

<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)第一种语法需要<button is="x-foo-button"></button>来创建文档中的实例2)第二种语法可用于任何元素,而不仅仅是自定义的扩展的?

1 个答案:

答案 0 :(得分:14)

回答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'
} )

newProtoHTMLButtonElement&#39; s prototype不同。

使用以下HTML代码:

<button is="x-foo-button" id="Hello" value="World"> Hello </button>

单击它将显示&#34; Hello World&#34;在弹出窗口中。

回答2 extends: 'button'是一个语义指示,告诉浏览器提供的新原型实现了HTMLButtonElement接口。这就是为什么从继承自HTMLButtonElement的对象开始更容易的原因。相反,您可以从HTMLFormElement原型开始,但您必须重新实现HTMLButtonElement接口的所有属性和方法。

如果不是,则元素行为将不正确。在上面的示例中,如果您将行替换为:

var newProto = Object.create( HTMLFormElement.prototype )

...单击它将失败,因为value元素中未实现属性<form>

属性id始终是正确的,因为它由HTMLElement接口提供,由每个元素(包括<form>)实现。

请注意,您可以添加缺少的属性,并将它们链接到attributeChangedCallback方法中的属性。

回答3 你是对的。这保持了与旧浏览器的向后兼容性,这些浏览器将忽略第二个参数,仍然能够创建普通元素(在您的示例中为标准<button>)。

回答4 自定义元素范例背后有两个不同的概念:

    如果要扩展标准HTML元素,请
  1. 输入扩展程序自定义内置元素)。
  2. 自定义标记自主自定义元素),如果要使用新名称定义自定义元素。
  3. 两者都使用相同的方法registerElement定义。 extends / is选项允许您选择其中一个。

    is语法仅适用于类型扩展,因此始终与extends选项相关联。

    使用 Type Extensions ,您可以保留所扩展元素的所有语义:CSS样式,内置行为(接口),辅助功能。向后兼容性是此语法的另一个好处。

    使用自定义标记,您将失去语义,并且您的自定义元素只能实现HTMLElement接口,没有内置样式或行为。

    更新:下一个示例(针对Chrome和Opera)说明了类型扩展程序自定义标记之间的区别。

    &#13;
    &#13;
    //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,
    })
    &#13;
    <!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>
    &#13;
    &#13;
    &#13;