Могат ли обратните извиквания на жизнения цикъл в персонализиран елемент на HTML5 да бъдат дефинирани след регистрация?

Напоследък работя с персонализирани елементи на HTML5 и се натъкнах на разочароващ проблем. Като се има предвид следното HTML тяло във всички примери:

<body>
    <h2>Foo elements.</h2>
    <foo-element>One!</foo-element>
    <foo-element>Two!</foo-element>
</body>

И този скрипт, прикачен към главата на страницата за регистриране на персонализирания елемент:

var HTMLFooElement = document.registerElement('foo-element', {
  prototype: Object.create(HTMLDivElement.prototype, {
    createdCallback: { value: function() {
      console.log('[CALLBACK] created: ', this);
    }},
    attachedCallback: { value: function() {
      console.log('[CALLBACK] attached: ', this);
    }}
  })
});

Приложението ще работи както се очаква на Chromium версия 41.0.2272.76: декларираните персонализирани елементи ще задействат и двете обратни извиквания, отпечатвайки 4 реда на конзолата.

[CALLBACK] created: <foo-element>One!</foo-element> [CALLBACK] attached: <foo-element>One!</foo-element> [CALLBACK] created: <foo-element>Two!</foo-element> [CALLBACK] attached: <foo-element>Two!</foo-element>

Но сега имах този случай на употреба, при който трябва да отложа дефиницията на attachedCallback за бъдещ случай:

var HTMLFooElement = document.registerElement('foo-element', {
  prototype: Object.create(HTMLDivElement.prototype, {
    createdCallback: { value: function() {
      console.log('[CALLBACK] created: ', this);
    }},
  })
});
HTMLFooElement.prototype.attachedCallback = function() {
  console.log('[CALLBACK] attached: ', this);
};

Оказва се, че тази версия няма да задейства attachedCallback и не се отпечатват "прикачени" редове в журнал (jsfiddle) . Функцията със сигурност ще бъде във всички мои персонализирани елементи като член в този момент, тъй като целият код е изпълнен преди да бъде обработена частта body на DOM. И независимо от това, резултатът е същият при създаване и добавяне на нови елементи в JavaScript след зареждане на документа.

Обърква ме, че не се прилагат късни дефиниции на обратно извикване на жизнения цикъл след регистриране на потребителския етикет. Какво трябва да направя, за да дефинирам обратно извикване на жизнения цикъл след извикване на registerElement и действително да го направя ефективно?


person E_net4 the curator    schedule 24.03.2015    source източник
comment
Изглежда, че е необходимо да регистрирате отново вашия елемент (не съм сигурен, че това дори е възможно), тъй като той няма да се актуализира автоматично. Това може да е напълно погрешно, но отговаря на симптомите.   -  person adamdc78    schedule 24.03.2015
comment
Разбирам, че трябва да обвържете персонализирания API, преди да извикате registerElement()   -  person wahwahwah    schedule 24.03.2015


Отговори (1)


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

var protoProxy = {
    createdCallback: function(e) {
        console.log('[CALLBACK] created: ', e);
    },
    attachedCallback: function(e) {
      console.log('[CALLBACK] placeholding ...');
    }
};
var HTMLFooProto = Object.create(HTMLDivElement.prototype, {
  createdCallback: { value: function() {
      protoProxy.createdCallback(this);
  }},
  attachedCallback: { value: function() {
      protoProxy.attachedCallback(this);
    }}
});

var HTMLFooElement = document.registerElement('foo-element', {
  prototype: HTMLFooProto
});

protoProxy.attachedCallback = function(e) {
  console.log('[CALLBACK] attached: ', e);
};

jsFiddle

person E_net4 the curator    schedule 30.03.2015
comment
Прав си. Спецификацията се е променила доста значително след v0 (без повече document.registerElement). Текущата спецификация изрично посочва, че обратните извиквания на жизнения цикъл се копират само когато елементът е дефиниран: w3.org/TR/custom-elements/#element-definition - person Noah Freitas; 22.10.2016