Подтвердить что ты не робот

Как получить список зарегистрированных пользовательских элементов

Я пытаюсь определить, был ли зарегистрирован пользовательский элемент с определенным именем или нет. Есть ли способ сделать такую ​​проверку?

Или есть способ получить список зарегистрированных пользовательских элементов?

Я делаю document.registerElement, но что еще там? Это односторонний API?

4b9b3361

Ответ 1

Существует способ проверить, был ли элемент зарегистрирован. У зарегистрированных элементов есть свои собственные конструкторы, в то время как незарегистрированные будут использовать простой HTMLElement() для конструктора (или HTMLUnknownElement(), является ли имя недопустимым, но это выходит за рамки вопроса):

document.registerElement('x-my-element');
document.createElement('x-my-element').constructor
//⇒ function x-my-element() { [native code] }
document.createElement('x-my-element-not-registered').constructor
//⇒ function HTMLElement() { [native code] }

Тем не менее, проверитель может выглядеть так:

var isRegistered = function(name) {
  return document.createElement(name).constructor !== HTMLElement;
}

Или с синтаксическим сахаром:

String.prototype.isRegistered = function() { 
  return document.createElement(this).constructor !== HTMLElement; 
}
'x-my-element'.isRegistered()
//⇒ true
'xx-my-element'.isRegistered()
//⇒ false

В основном осторожная версия:

String.prototype.wasRegistered = function() { 
  switch(document.createElement(this).constructor) {
    case HTMLElement: return false; 
    case HTMLUnknownElement: return undefined; 
  }
  return true;
}
'x-my-element'.wasRegistered()
//⇒ true
'xx-my-element'.wasRegistered()
//⇒ false
'xx'.wasRegistered()
//⇒ undefined

Нет доступа к списку зарегистрированных элементов, AFAIK.

Кстати, я до сих пор считаю, что попытка регистрации (как предложено @stephan-muller) лучше подходит для ваших нужд.

Ответ 2

В настоящее время не существует способа увидеть все зарегистрированные элементы, но есть способ проверить, был ли уже зарегистрирован элемент: заверните регистр в блок try...catch:

try {
    document.registerElement('x-my-element');
} catch(e) {
    console.log('already exists', e);
}

Запустите это дважды в консоли, и вы увидите сообщение об ошибке.

У этого есть недостаток, если вы просто хотите проверить, зарегистрирован ли он или нет: если бы это было не так, это произойдет после его запуска. Также нет способа отменить регистрацию элемента, который кажется.

Ответ 3

Хотя я не уверен, что это относится к другим структурам веб-компонентов, при использовании Polymer в Chrome у меня есть объект CustomElements для объекта window. Объект CustomElements имеет коллекцию ключей/значений всех зарегистрированных пользовательских элементов, называемых registry.

function isRegistered(name) {
    if (window.CustomElements && window.CustomElements.registry)
        return name in window.CustomElements.registry;
    return undefined;
}

Ответ 4

Объединяя несколько из приведенных выше подходов, вы можете перебирать все используемое и выплевывать уникальный список пользовательских (и зарегистрированных) элементов:

function isRegistered(name) {
  return document.createElement(name).constructor.__proto__ !== window.HTMLElement;
}

var allElems = document.querySelectorAll('html /deep/ *');
var nodeNames = [].map.call(allElems, el => el.nodeName.toLowerCase())
                    .filter((value, index, self) => self.indexOf(value) === index)

console.log('all elements', nodeNames);
console.log('registered, custom elements', nodeNames.filter(isRegistered))

введите описание изображения здесь

Ответ 5

Поскольку пользовательские элементы теперь являются частью последнего стандарта, я думал, что поделился бы тем, как это сделать в 2017 году +:

Примечание: функция document.registerElement была устарела в пользу customElements.define().

customElements определяется как глобальное значение в window. Существует три метода:

  • define
  • get
  • whenDefined

get является важным здесь. get принимает string имени элемента и возвращает конструктор для именованного настраиваемого элемента или undefined, если для имени нет определенного определения элемента.

Итак, в 2017 году, чтобы проверить, зарегистрирован ли элемент, вы:

const myElementExists = !!customElements.get('my-element');

Я не уверен, есть ли способ получить список определенных элементов. Важно также отметить, что хром является единственным браузером, который определяет это изначально в этот момент времени. CustomElements v1 являются частью стандарта, поэтому это не является частью Polymer, если кто-то задавался вопросом, но они сделали сделать polyfill для него.

Ответ 6

Как уже написано на канале Polymer Slack, это грязный, который может сделать работу:

function isElementRegistered(elementId) {
  return Polymer.telemetry.registrations.find(function(item) { return item.is === elementId })
}

Не уверен, насколько Polumer.telemetry.registrations является надежным, хотя (не видел его в документе), а Array.prototype.find не является кросс-браузером!

Ответ 7

в сценариях, где пользовательские классы элементов (конструкторы) самостоятельно регистрируют элемент, достаточно проверить наличие класса