特定の名前のカスタム要素が登録されているかどうかを検出しようとしています。そのようなチェックを行う方法はありますか?
または、登録されたカスタム要素のリストを取得する方法はありますか?
私がやります document.registerElement
、しかし他に何がありますか?一方向のAPIですか?
要素が登録されているかどうかを確認する方法があります。登録された要素には独自のコンストラクターがありますが、登録されていないものはコンストラクターにプレーン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にアクセスする方法はありません。
ところで、私はtry-catched登録(@ stephan-mullerが提案)があなたのニーズにより適しているとまだ思います。
上記のアプローチのいくつかを組み合わせると、使用中のすべてを反復して、カスタム(および登録済み)要素の一意のリストを吐き出すことができます。
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))
カスタム要素が 最新の標準 の一部になっているので、2017 +でこれを行う方法を共有すると思いました:
注:
document.registerElement
関数が追加されました customElements.define()。の採用により非推奨
customElements
はwindow
でグローバルとして定義されています。 つのメソッドが定義されています :
define
get
whenDefined
ここではget
が重要です。 get
は要素名のstring
を取り、名前付きカスタム要素のコンストラクターを返します。名前にカスタム要素定義がない場合はundefined
を返します。
2017年以降、要素が登録されているかどうかを確認するには:
const myElementExists = !!customElements.get('my-element');
しかし、定義された要素のリストを取得する方法があるかどうかはわかりません。
注:これはIEでは機能しません。 ブラウザの互換性についてはこちらをご覧ください
現在、登録されているすべての要素を確認する方法はないようですが、要素がすでに登録されているかどうかを確認する方法があります。レジスタをtry...catch
ブロックでラップします。
try {
document.registerElement('x-my-element');
} catch(e) {
console.log('already exists', e);
}
コンソールでこれを2回実行すると、ログに記録されたエラーが表示されます。
ただし、登録されているかどうかを確認したいだけの場合は欠点があります。登録されていない場合は、これを実行した後になります。要素の登録を解除する方法もありません。
他のWebコンポーネントフレームワークに適用されるかどうかはわかりませんが、ChromeでPolymerを使用している場合、CustomElements
オブジェクトからwindow
オブジェクトへのオブジェクトがあります。CustomElements
オブジェクトには、登録されているすべてのキー/値のコレクションがあります。 registry
と呼ばれるカスタム要素。
function isRegistered(name) {
if (window.CustomElements && window.CustomElements.registry)
return name in window.CustomElements.registry;
return undefined;
}
PolymerのSlackチャネルで既に書かれているように、これは仕事をすることができる汚いものです:
function isElementRegistered(elementId) {
return Polymer.telemetry.registrations.find(function(item) { return item.is === elementId })
}
どれくらいかわからないPolumer.telemetry.registrations
は信頼できますが(ドキュメントでは見ていません)、Array.prototype.find
はクロスブラウザではありません!
カスタム要素クラス(コンストラクタ)が要素を自己登録するシナリオでは、クラスの存在を確認するだけで十分です