Ответ 1
Ответ 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 В парадигме Custom Elements есть две разные концепции:
- Расширения типов (настраиваемые встроенные элементы), если вы хотите расширить стандартный элемент HTML.
- Пользовательский тег (автономные пользовательские элементы), если вы хотите определить пользовательские элементы с новыми именами.
Оба определены с помощью того же метода registerElement
. Опция extends
/is
позволяет выбрать один из них.
Синтаксис is
работает только с расширениями типов и поэтому всегда связан с опцией extends
.
С помощью Type Extensions вы сохраняете всю семантику расширяемого элемента: стили 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>