在Web组件中扩展元素时,“ is”语法的意义是什么?

默克

在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.prototypeand 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>,这使我想到下一个问题:

问题4is语法的重点是什么?这样做之间的实际区别是什么:

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明显的重复是因为您的示例非常简单。在实际的虚拟生活中,您将为提供不同的原型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比不同HTMLButtonElementprototype

使用以下HTML代码:

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

单击它会在弹出窗口中显示“ Hello World”。


答案2extends: 'button'是语义指示,告诉了新的原型提供实现浏览器HTMLButtonElement界面。因此,从继承自的对象开始比较容易HTMLButtonElement相反,您可以从HTMLFormElement原型开始,但必须重新实现HTMLButtonElement接口的所有属性和方法

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

var newProto = Object.create( HTMLFormElement.prototype )

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

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

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


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


答案4自定义元素”范例背后有2个不同的概念

  1. 如果要扩展标准HTML元素,请键入扩展名自定义内置元素)。
  2. 如果要使用新名称定义自定义元素,请使用“自定义标签”(“自治的自定义元素”)。

两者都用相同的方法定义registerElementextends/is选项允许你选择其中之一。

is语法仅与类型扩展一起使用,因此始终与该extends选项关联

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

使用Custom Tags,您可以松开语义,并且期望您的custom元素仅实现HTMLElement接口,而没有内置样式或行为。

更新:下一个示例(适用于Chrome和Opera)说明了Type ExtensionCustom Tag之间的区别

//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>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

CIL中的nop的意义是什么

来自分类Dev

语法Haskell中的@是什么?

来自分类Dev

Lua中嵌套括号的意义是什么?

来自分类Dev

Repository EF模式中Update函数的意义是什么?

来自分类Dev

Xcode中堆栈跟踪的意义是什么?

来自分类Dev

Java中的数组语法:[]位置的意义是什么

来自分类Dev

#if 1在C中的意义是什么

来自分类Dev

输入标签中cmdValue的意义是什么?

来自分类Dev

Systemui APK在Android中的意义是什么?

来自分类Dev

glBufferData中目标参数的意义是什么

来自分类Dev

(int *)在此程序中的意义是什么?

来自分类Dev

SpriteKIT中的anchorPoint属性的意义是什么?

来自分类Dev

Python中float('inf')的意义是什么?

来自分类Dev

组件<{},{},状态>。React中的语法是什么?

来自分类Dev

bash中的@(... | ... | ...)语法是什么?

来自分类Dev

制作计步器时onAccuracyChanged方法的意义是什么?

来自分类Dev

REDIS在ELK堆栈中的意义是什么?

来自分类Dev

C中__unused属性的意义是什么?

来自分类Dev

语法Haskell中的@是什么?

来自分类Dev

FormData中[1]的意义是什么?

来自分类Dev

#if 1在C中的意义是什么

来自分类Dev

dd(1)中(1)的意义是什么?

来自分类Dev

Systemui APK在Android中的意义是什么?

来自分类Dev

glBufferData中目标参数的意义是什么

来自分类Dev

(int *)在此程序中的意义是什么?

来自分类Dev

弹性搜索中类型的意义是什么?

来自分类Dev

在 HTML 中使用令牌时 CSRF 保护的意义是什么

来自分类Dev

$ref 在 Odata 4 中的意义是什么

来自分类Dev

FILE结构中`_flag`的意义是什么?