2017-03-27 14 views
0

HTML specには、CustomElementRegistryに格納されているいくつかの種類の要素が記述されています。 HTMLAnchorElementのHTMLElementの組み込みサブクラスで表される<a>カスタムHTML要素

  1. 組み込み要素。
  2. <my-element>のような自律カスタム要素は、HTMLElementを拡張し、CustomElementRegistryに登録してください。
  3. Customized builtin elements<a is="my-link">のように、HTMLElementのサブクラスを拡張し、is="customized-tag-name"を使用してクラスを指定します。 (まだ?)による遅れスクリプトの読み込みにおそらく登録されていないHTMLUnknownElement
  4. Customizable elementsを拡張<isindex>よう
  5. Legacy elements

要素がどのバケットに属しているかを実行時に把握する方法はありますか?

答えて

1

下記の[jsbin]の種類は、"[native code]"のコンストラクタをテストせずに仕事をして管理しますが、要素が組み込まれているかどうかを判断する良い方法があるはずです。

//<script> 

// https://w3c.github.io/webcomponents/spec/custom/#valid-custom-element-name 
var VALID_CUSTOM_ELEMENT_NAME_REGEX = /^(?!(?:annotation-xml|color-profile|font-face|font-face(?:-(?:src|uri|format|name))?|missing-glyph)$)[a-z][a-z.0-9_\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u200C\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uDFFF\uF900-\uFDCF\uFDF0-\uFFFD]*-[\-a-z.0-9_\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u200C\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uDFFF\uF900-\uFDCF\uFDF0-\uFFFD]*$/; 

function classify(el) { 
    var name = el.localName; 
    // TODO: are elements from a different document dealt with by that 
    // document's CustomElementRegistry? 
    // How do we get from a document to a CustomElementRegistry? 
    // Maybe just assert el.ownerDocument === document? 
    // Does that screw up elements from <template> content. 
    if (customElements.get(name)) { return 'custom'; } 
    // TODO: check that the value of is="..." is registered 
    if (el.getAttribute('is')) { return 'custom-builtin'; } 
    var ctor = el.constructor; 
    if (ctor === HTMLUnknownElement) { return 'legacy'; } 
    if (ctor === HTMLElement) { 
    if (VALID_CUSTOM_ELEMENT_NAME_REGEX.test(name)) { 
     return 'customizable'; 
    } 
    } 
    return 'builtin'; 
} 


// A bunch of element names from MDN and elsewhere to test 
var names = [ 
    "a", "abbr", "acronym", "address", "applet", 
    "annotation-xml", "area", 
    "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", 
    "bgsound", "big", "blink", "blockquote", "body", "br", "button", 
    "canvas", "caption", "center", "cite", "code", "col", "colgroup", 
    "command", "content", "data", "datalist", "dd", "del", "details", 
    "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "embed", 
    "fieldset", "figcaption", "figure", "font", "footer", "form", 
    "frame", "frameset", "h1", "h6", "head", "header", "hgroup", "hr", 
    "html", "i", "iframe", "image", "img", "input", "ins", "isindex", 
    "kbd", "keygen", "label", "legend", "li", "link", "listing", "main", 
    "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", 
    "multicol", "nav", "nobr", "noembed", "noframes", "noscript", 
    "object", "ol", "optgroup", "option", "output", "p", "param", 
    "picture", "plaintext", "pre", "progress", "q", "rp", "rt", "rtc", 
    "ruby", "s", "samp", "script", "section", "select", "shadow", 
    "slot", "small", "source", "spacer", "span", "strike", "strong", 
    "style", "sub", "summary", "sup", "table", "tbody", "td", 
    "template", "textarea", "tfoot", "th", "thead", "time", "title", 
    "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", 
    "isindex", // Known legacy element 
    "un-registered", "reg-istered"]; // Test custom/customizable 

//</script><script> 

class MyElement extends HTMLElement { 
    constructor() { 
    super(); 
    } 
} 

customElements.define('reg-istered', MyElement); 

//</script><script> 
var table = document.createElement('table'); 
document.body.appendChild(table); 
var tbody = document.createElement('tbody'); 
table.appendChild(tbody); 
function addRowForElement(el) { 
    var tr = document.createElement('tr'); 
    tbody.appendChild(tr); 
    var td0 = document.createElement('td'); 
    tr.appendChild(td0); 
    td0.appendChild(document.createTextNode(el.outerHTML)); 
    var td1 = document.createElement('td'); 
    tr.appendChild(td1); 
    td1.appendChild(document.createTextNode('' + classify(el))); 
} 
for (var i = 0, n = names.length; i < n; ++i) { 
    addRowForElement(document.createElement(names[i])); 
} 
var customBi = document.createElement('input'); 
customBi.setAttribute('is', 'my-custom-input'); // Not yet registered. 
addRowForElement(customBi); 
//</script><style>td:first-child { font-family: monospace }</style> 
+1

'(customElements.get())'は、登録されたカスタマイズされた組み込み要素に対しても 'true'を返します。 – Supersharp

+0

@supersharp、良い点 –