2014-01-14 3 views
4

Если создать пользовательский элемент следующегоизменение прототипа пользовательского элемента

document.register('bar-foo', { prototype: { .... } }); // or document.registerElement 

Теперь, после этого я хотел бы добавить что-то прототип этого элемента.

Например, я могу сделать это с помощью элемента «сНа»:

HTMLDivElement.prototype.bar = function() {}; 
document.createElement('div').bar(); 

Как бы я сделать это с моим настраиваемым элементом «штрих-Foo»?

+1

Что такое document.register? Никогда не слышал об этом, и, похоже, об этом нет на MDN. – bjb568

+3

@ bjb568 Только что нашел это, посмотрите раздел 5.5: http://w3c.github.io/webcomponents/explainer/#defining-a-custom-element –

+0

спасибо большое, это именно то, что мне нужно. Ваше предложение ниже будет работать, но это лучше! –

ответ

1

Я не нашел много на register, и мало найти на registerElement, но если он следует остаток прототипных наследования в JavaScript, вы должны быть в состоянии сохранить объект, который дает прототип и изменить его позже, например:

var saveMe = {}; 
document.register('bar-foo', saveMe); 
saveMe.prototype = { 
    // ... 
} 
2

Я реализовал пользовательские элементы в Chrome, поэтому я знаком с этим. (FWIW document.register было переименовано в document.registerElement.)

Чтобы добавить что-то к прототипу пользовательского элемента позже, вам сначала потребуется ссылка на объект-прототип.

В вашем вопросе вы получаете доступ к прототипу через конструктор для DIV, HTMLDivElement.prototype. Вы можете использовать аналогичный шаблон в пользовательских элементах. Конструктор Custom Element возвращается из registerElement. При сохранении ссылки на него вы можете использовать его для доступа прототип позже: (. Вы можете также использовать возвращаемый объект, который спецификация вызывает сгенерированного конструктор для создания элементов с использованием new BarFoo())

BarFoo = document.registerElement('bar-foo', ...); 

// later 
BarFoo.prototype.foo = ... 

Имеет смысл сохранить ссылку на глобальный объект (окно), потому что это так, как это делается в таких элементах, как HTMLDivElement, хотя вам этого не нужно.

При разработке спецификации мы рассмотрели возможность создания ссылки на этот конструктор на автоматическом окне, но решили, что меньше магии и меньше загрязнений имен лучше. Мы также рассмотрели возможность добавления объекта, с помощью которого вы могли бы передать имя тега и вернуть правильный конструктор. Мы хотели сделать эту работу для встроенных элементов, а также для пользовательских элементов. К сожалению, это предложение долгое время не выдерживало пересмотра стандартов.

Существуют и другие способы делать то, что вы хотите. Например, вместо сохранения ссылки на сгенерированный конструктор вы можете напрямую сохранить ссылку на прототип. Кроме того, если у вас есть экземпляр пользовательского элемента, вы можете использовать Object.getPrototypeOf(elem) или elem.__proto__ для получения объекта-прототипа.

HTH!

+0

Возможно, это было правильно, но оно больше не является правильным. platform.js для IE10 не работает, если registerElement не вызван модифицированным прототипом; это также не работает для firefox или chrome (но без ошибок). – Doug

+0

@Doug Извините, а какая часть не права? –

+0

Текущая версия platform.js не поддерживает модификацию прототипа значения, возвращаемого из registerElement(). Я не знаю, было ли это в прошлом, но то, что вы предложили выше (var foo = docuement.registerElement (...); foo.prototype.bar = function() {...}) работает только в хром. Для поддержки кросс-браузера (точка platform.js ...: P) вам необходимо изменить прототип * до * вызова registerElement() – Doug

1

Прежде всего, это не сработает, если вы не используете platform.js, но если это так, вы должны привязать пользовательский api до, вызывающий регистрElement.

var prototype = Object.create(HTMLElement.prototype); 
prototype.createdCallback = function() { 
    ... 
}; 
prototype.mycall = function() { 
    console.log(this.shadowRoot.innerHTML); 
}; 
document.registerElement('my-type', { prototype: prototype }); 

Вы тогда будете в состоянии сделать это:

<my-type>100</my-type> 
<script> 
    document.getElementById('foo').mycall(); 
</script> 

Обратите внимание две вещи:

1) В соответствии с https://api.dartlang.org/apidocs/channels/be/dartdoc-viewer/dart-dom-html.HtmlDocument#id_registerElement, вызов registerElement не не возвращает значение. Platform.js соответствует этому. Не используйте возвращаемое значение, если оно есть (например, на хроме).

2) Начиная с platform.js 0.4.0, некоторые браузеры поддерживают вызов registerElement и , затем, ретроспективно добавляя вызовы прототипу. Это, в частности, не поддерживается для IE10.

Смежные вопросы