javascript 如何获取已注册的自定义元素列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27334365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get list of registered custom elements
提问by dy_
I'm trying to detect whether a custom element with a specific name was registered or not. Is there a way to make such check?
我正在尝试检测是否注册了具有特定名称的自定义元素。有没有办法进行这样的检查?
Or is there a way to get list of registered custom elements?
或者有没有办法获取已注册自定义元素的列表?
I do document.registerElement
, but what else is there? Is it one-way API?
我有document.registerElement
,但还有什么?它是单向 API 吗?
回答by Aleksei Matiushkin
There is a way to check whether an element was registered. Registered elements have their own constructors, while unregistered ones would use plain HTMLElement()
for constructor (or HTMLUnknownElement()
whether the name is not valid, but this is out of scope of the question):
有一种方法可以检查元素是否已注册。已注册的元素有自己的构造函数,而未注册的元素将使用普通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] }
That said, the checker might look like:
也就是说,检查器可能看起来像:
var isRegistered = function(name) {
return document.createElement(name).constructor !== HTMLElement;
}
Or, with syntactic sugar:
或者,使用语法糖:
String.prototype.isRegistered = function() {
return document.createElement(this).constructor !== HTMLElement;
}
'x-my-element'.isRegistered()
//? true
'xx-my-element'.isRegistered()
//? false
The mostly careful version:
最谨慎的版本:
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
There is no way to access a list of registered elements, AFAIK.
AFAIK 无法访问已注册元素列表。
BTW, I still think that the try-catchedregistration (as proposed by @stephan-muller) suits your needs better.
顺便说一句,我仍然认为try-catched注册(由@stephan-muller 提出)更适合您的需求。
回答by Rico Kahler
Since custom elements is now part of the latest standard, I thought I'd share how to do this in 2017+:
由于自定义元素现在是最新标准的一部分,我想我会在 2017 年以上分享如何做到这一点:
Note: the
document.registerElement
function has been deprecated in favor of customElements.define().
注意:该
document.registerElement
函数已被弃用,取而代之的是 customElements.define()。
customElements
is defined as a global in window
. There are three methods defined:
customElements
被定义为 中的全局变量window
。定义了三种方法:
define
get
whenDefined
define
get
whenDefined
get
is the important one here. get
takes a string
of the element name and returns the constructor for the named custom element, or undefined
if there is no custom element definition for the name.
get
是这里很重要的一个。get
获取string
元素名称的 a 并返回命名的自定义元素的构造函数,或者undefined
如果名称没有自定义元素定义。
So in 2017+ to check if an element has been registered do you:
因此,在 2017+ 年,要检查元素是否已注册,您是否:
const myElementExists = !!customElements.get('my-element');
I'm not sure if there's a way to get a list of defined elements however.
但是,我不确定是否有办法获取已定义元素的列表。
NOTE:this doesn't work in IE. See here for browser compatibility
注意:这在 IE 中不起作用。请参阅此处了解浏览器兼容性
回答by Paul Irish
Combining a few of the above approaches you can iterate over everything in use and spit out a unique list of custom (and registered) elements:
结合上述几种方法,您可以迭代使用中的所有内容并吐出自定义(和注册)元素的唯一列表:
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))
回答by Stephan Muller
There doesn't seem to a way to see all registered elements at the moment, but there is a way to check whether or not an element has been registered already: wrap the register in a try...catch
block:
目前似乎没有办法查看所有已注册的元素,但有一种方法可以检查元素是否已注册:将寄存器包装在一个try...catch
块中:
try {
document.registerElement('x-my-element');
} catch(e) {
console.log('already exists', e);
}
Run this twice in your console and you'll see the error logged.
在您的控制台中运行两次,您将看到记录的错误。
This does have a drawback if you simply want to check whether or not it was registered though: if it was not, it will be after running this. There also isn't a way to unregister an element it seems.
如果您只是想检查它是否已注册,这确实有一个缺点:如果没有,它将在运行后进行。似乎也没有办法取消注册元素。
回答by Fuzzical Logic
While I am not sure it applies to other Web Component frameworks, while using Polymer in Chrome, I have a CustomElements
object to the window
object. The CustomElements
object has a key/value collection of all registered custom elements called registry
.
虽然我不确定它是否适用于其他 Web 组件框架,但在 Chrome 中使用 Polymer 时,我有一个CustomElements
对象指向该window
对象。该CustomElements
对象具有所有注册的自定义元素的键/值集合,称为registry
。
function isRegistered(name) {
if (window.CustomElements && window.CustomElements.registry)
return name in window.CustomElements.registry;
return undefined;
}
回答by lzzluca
As written already on the Polymer's Slack channel, this is a dirty one that can make the job:
正如已经在 Polymer 的 Slack 频道上写的那样,这是一个可以完成这项工作的肮脏的频道:
function isElementRegistered(elementId) {
return Polymer.telemetry.registrations.find(function(item) { return item.is === elementId })
}
Not sure how much Polumer.telemetry.registrations
is reliable though (haven't seen it on the doc) and Array.prototype.find
is not cross-browser!
不确定多少Polumer.telemetry.registrations
是可靠的(在文档上没有看到)并且Array.prototype.find
不是跨浏览器!
回答by Markus
in scenarios where custom element classes (constructors) self-register an element, it is sufficient to check for the presence of the class
在自定义元素类(构造函数)自注册元素的情况下,检查该类是否存在就足够了