浏览器支持的所有HTML标记

Hug*_*ugo 11 html javascript browser

使用JavaScript,是否可以获得浏览器支持的标签列表?

rec*_*ive 5

如果您愿意从已知的候选标签列表开始,您可以尝试这样的事情:

document.createElement("asdf") instanceof HTMLUnknownElement
true
document.createElement("canvas") instanceof HTMLUnknownElement
false
Run Code Online (Sandbox Code Playgroud)

如果您需要支持IE8,可以使用以下方法:

function browserSupports(elementTagName) {
    var el = document.createElement(elementTagName);
    return !((el instanceOf HTMLUnknownElement) || (el instanceof HTMLGenericElement));
}
Run Code Online (Sandbox Code Playgroud)

这是另一种不依赖于特定命名构造函数的方法.

function browserSupports(elementTagName) {
    var unknownel = document.createElement("zzxcv");
    var el = document.createElement(elementTagName);
    return unknownel.constructor !== el.constructor;
}
Run Code Online (Sandbox Code Playgroud)

但它似乎仍然无法在IE8中运行.


Dan*_*ams 5

您可以对窗口中的自省所支持的内容有个体面的想法。

试试看:

props = Object.getOwnPropertyNames(window)
for (var idx in props) {
  if (props[idx].indexOf("HTML") == 0) {
    //do something here
    console.log(props[idx]);
  }  
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这绝不是详尽无遗的,但是它将告诉您在大多数浏览器中哪些标签具有DOM对象类型。

这是在Chrome控制台中运行此示例输出:

HTMLUnknownElement
HTMLOptionsCollection
HTMLFormControlsCollection
HTMLAllCollection
HTMLCollection
HTMLUListElement
HTMLTitleElement
HTMLTextAreaElement
HTMLTemplateElement
HTMLTableSectionElement
HTMLTableRowElement
HTMLTableElement
HTMLTableColElement
HTMLTableCellElement
HTMLTableCaptionElement
HTMLStyleElement
HTMLSpanElement
HTMLSelectElement
HTMLScriptElement
HTMLQuoteElement
HTMLProgressElement
HTMLPreElement
HTMLParamElement
HTMLParagraphElement
HTMLOutputElement
HTMLOptionElement
HTMLOptGroupElement
HTMLObjectElement
HTMLOListElement
HTMLModElement
HTMLMeterElement
HTMLMetaElement
HTMLMenuElement
HTMLMarqueeElement
HTMLMapElement
HTMLLinkElement
HTMLLegendElement
HTMLLabelElement
HTMLLIElement
HTMLKeygenElement
HTMLInputElement
HTMLImageElement
HTMLIFrameElement
HTMLHtmlElement
HTMLHeadingElement
HTMLHeadElement
HTMLHRElement
HTMLFrameSetElement
HTMLFrameElement
HTMLFormElement
HTMLFontElement
HTMLFieldSetElement
HTMLEmbedElement
HTMLDivElement
HTMLDirectoryElement
HTMLDataListElement
HTMLDListElement
HTMLCanvasElement
HTMLButtonElement
HTMLBodyElement
HTMLBaseElement
HTMLBRElement
HTMLAreaElement
HTMLAppletElement
HTMLAnchorElement
HTMLElement
HTMLDocument
Run Code Online (Sandbox Code Playgroud)

  • 这很有趣,但是它提供了一个接口列表,而不是元素类型列表。例如,列表不包含任何与“ strong”或“ span”相对应的内容,因为这些元素没有自己的接口(它们仅使用通用HTMLElement接口)。 (2认同)

Mar*_*tke 5

每个由document.createElement()创建的JavaScript html元素对象都有一个构造函数,它总是以“HTML...”开头并以“...Element”结尾。所有这些都继承自 HTMLElement。每个都可以通过Object.getOwnPropertyNames()window对象中访问。

因此,您可以通过遍历 window 中的所有属性名称来获取所有有效的标记名称,并使用HTML...ELement对其进行过滤:

function getAllTagNames()
{
    let names = [];

    Object.getOwnPropertyNames(window).forEach(name =>
    {
        if(name.startsWith('HTML') && name.endsWith('Element') && Object.getPrototypeOf(window[name]) == HTMLElement)
        {
            names.push(name.substr(4, name.length - 11).toLowerCase());
        }
    });

    names.sort((left, right) =>
    {
        if(left.toLowerCase) { left = left.toLowerCase(); }
        if(right.toLowerCase) { right = right.toLowerCase(); }

        return left == right ? 0 : (left < right ? -1 : 1);
    });

    return names;
}
Run Code Online (Sandbox Code Playgroud)

如何使用它:

console.log(getAllTagNames()); // [anchor", "area", "base", "body", "br", ...]
Run Code Online (Sandbox Code Playgroud)

编辑

一些 html 元素的构造函数只是基本构造函数(例如HTMLMediaElement)。在这种情况下,HTMLAudioElement ( <audio></audio> ) 和HTMLVideoElement ( <video></video> )的基本构造函数不是直接从HTMLElement继承的。所以需要跑遍完整的原型链,instanceof操作符适合这个:

window['HTMLAudioElement'].prototype instanceof HTMLElement
Run Code Online (Sandbox Code Playgroud)

另一方面是一些构造函数名称不适合等效的 html 标签名称(< a > => HTML元素),而其他一些名称适合多个标签(例如<h1></h1>、<h2></ h2>, <h3></h3>, <h4></h4>, <h5></h5>, <h6></h6>)具有相同的构造函数。> 见 mdn。

目前,在 JavScript 中没有其他方法可以使用 document.createElement(tagName); 创建错误的标识标签名称,请检查构造函数是否为 HTMLUnknownElement 并手动修复这些:

function getAllTagNames()
{
    let items = [];

    Object.getOwnPropertyNames(window).forEach(name =>
    {
        if(name.startsWith('HTML') && name.endsWith('Element') && window[name].prototype instanceof HTMLElement)
        {
            items.push({ constructorName: name, tagName: name.substr(4, name.length - 11).toLowerCase() });
        }
    });

    items.sort((leftItem, rightItem) =>
    {
        let left = leftItem.tagName;
        let right = rightItem.tagName;

        if(left.toLowerCase) { left = left.toLowerCase(); }
        if(right.toLowerCase) { right = right.toLowerCase(); }

        return left == right ? 0 : (left < right ? -1 : 1);
    });

    function insertSorted(item)
    {
        let index = 0;
        while(item.tagName > items[index].tagName) { index++; }
        items.splice(index, 0, item);
    }

    let disagreements = [];
    items = items.filter(item =>
    {
        let tagName = item.tagName;

        switch(tagName) // deprecated
        {
            case "keygen": return false;
        }

        let filter = tagName == "unknown" || document.createElement(tagName).constructor == HTMLUnknownElement;
        if(filter && tagName != "unknown") { disagreements.push(item); }

        return !filter;
    });

    disagreements = disagreements.filter(item =>
    {
        switch(item.tagName) // base constructor
        {
            case "media": return false;
        }

        return true;
    });

    disagreements.forEach(item => 
    {
        let tagName = item.tagName;

        function exchange(tagName)
        {
            insertSorted({ constructorName: item.constructorName, tagName: tagName });
        }

        switch(tagName)
        {
            case 'anchor':
                exchange('a');
                break;

            case 'directory':
                exchange('dir');
                break;

            case 'dlist':
                exchange('dl');
                break;

            case 'heading':
                exchange('h1');
                exchange('h2');
                exchange('h3');
                exchange('h4');
                exchange('h5');
                exchange('h6');
                break;

            case 'image':
                exchange('img');
                break;

            case 'mod':
                exchange('del');
                exchange('ins');
                break;

            case 'olist':
                exchange('ol');
                break;

            case 'paragraph':
                exchange('p');
                break;

            case 'quote':
                exchange('blockquote');
                exchange('q');
                break;

            case 'tablecaption':
                exchange('caption');
                break;

            case 'tablecell':
                exchange('th');
                exchange('td');
                break;

            case 'tablecol':
                exchange('col');
                exchange('colgroup');
                break;

            case 'tablerow':
                exchange('tr');
                break;

            case 'tablesection':
                exchange('tfoot');
                exchange('thead');
                exchange('tbody');
                break;

            case 'ulist':
                exchange('ul');
                break;

            default:
                console.log('disagree', tagName);
                if(console.warn && tagName != "") { console.warn("unknown tag name for " + item.constructorName); }
                break;
        }
    });

    return items.map(item => item.tagName);
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

let tagNames =
[
    { name: "a", constr: "HTMLAnchorElement" },
    { name: "area", constr: "HTMLAreaElement" },
    { name: "audio", constr: "HTMLAudioElement" },
    { name: "base", constr: "HTMLBaseElement" },
    { name: "body", constr: "HTMLBodyElement" },
    { name: "br", constr: "HTMLBRElement" },
    { name: "button", constr: "HTMLButtonElement" },
    { name: "canvas", constr: "HTMLCanvasElement" },
    { name: "content", constr: "HTMLContentElement" },
    { name: "data", constr: "HTMLDataElement" },
    { name: "datalist", constr: "HTMLDataListElement" },
    { name: "details", constr: "HTMLDetailsElement" },
    { name: "dialog", constr: "HTMLDialogElement" },
    { name: "dir", constr: "HTMLDirectoryElement" },
    { name: "div", constr: "HTMLDivElement" },
    { name: "dl", constr: "HTMLDListElement" },
    { name: "embed", constr: "HTMLEmbedElement" },
    { name: "fieldset", constr: "HTMLFieldSetElement" },
    { name: "font", constr: "HTMLFontElement" },
    { name: "form", constr: "HTMLFormElement" },
    { name: "frame", constr: "HTMLFrameElement" },
    { name: "frameset", constr: "HTMLFrameSetElement" },
    { name: "head", constr: "HTMLHeadElement" },
    { name: "h1", constr: "HTMLHeadingElement" },
    { name: "h2", constr: "HTMLHeadingElement" },
    { name: "h3", constr: "HTMLHeadingElement" },
    { name: "h4", constr: "HTMLHeadingElement" },
    { name: "h5", constr: "HTMLHeadingElement" },
    { name: "h6", constr: "HTMLHeadingElement" },
    { name: "hr", constr: "HTMLHRElement" },
    { name: "html", constr: "HTMLHtmlElement" },
    { name: "iframe", constr: "HTMLIFrameElement" },
    { name: "img", constr: "HTMLImageElement" },
    { name: "input", constr: "HTMLInputElement" },
    { name: "label", constr: "HTMLLabelElement" },
    { name: "legend", constr: "HTMLLegendElement" },
    { name: "li", constr: "HTMLLIElement" },
    { name: "link", constr: "HTMLLinkElement" },
    { name: "map", constr: "HTMLMapElement" },
    { name: "marquee", constr: "HTMLMarqueeElement" },
    { name: "menu", constr: "HTMLMenuElement" },
    { name: "meta", constr: "HTMLMetaElement" },
    { name: "meter", constr: "HTMLMeterElement" },
    { name: "del", constr: "HTMLModElement" },
    { name: "ins", constr: "HTMLModElement" },
    { name: "object", constr: "HTMLObjectElement" },
    { name: "ol", constr: "HTMLOListElement" },
    { name: "optgroup", constr: "HTMLOptGroupElement" },
    { name: "option", constr: "HTMLOptionElement" },
    { name: "output", constr: "HTMLOutputElement" },
    { name: "p", constr: "HTMLParagraphElement" },
    { name: "param", constr: "HTMLParamElement" },
    { name: "picture", constr: "HTMLPictureElement" },
    { name: "pre", constr: "HTMLPreElement" },
    { name: "progress", constr: "HTMLProgressElement" },
    { name: "q", constr: "HTMLQuoteElement" },
    { name: "script", constr: "HTMLScriptElement" },
    { name: "select", constr: "HTMLSelectElement" },
    { name: "shadow", constr: "HTMLShadowElement" },
    { name: "slot", constr: "HTMLSlotElement" },
    { name: "source", constr: "HTMLSourceElement" },
    { name: "span", constr: "HTMLSpanElement" },
    { name: "style", constr: "HTMLStyleElement" },
    { name: "td", constr: "HTMLTableCellElement" },
    { name: "th", constr: "HTMLTableCellElement" },
    { name: "col", constr: "HTMLTableColElement" },
    { name: "colgroup", constr: "HTMLTableColElement" },
    { name: "table", constr: "HTMLTableElement" },
    { name: "tr", constr: "HTMLTableRowElement" },
    { name: "tbody", constr: "HTMLTableSectionElement" },
    { name: "tfoot", constr: "HTMLTableSectionElement" },
    { name: "thead", constr: "HTMLTableSectionElement" },
    { name: "template", constr: "HTMLTemplateElement" },
    { name: "time", constr: "HTMLTimeElement" },
    { name: "title", constr: "HTMLTitleElement" },
    { name: "track", constr: "HTMLTrackElement" },
    { name: "ul", constr: "HTMLUListElement" },
    { name: "video", constr: "HTMLVideoElement" }
];
Run Code Online (Sandbox Code Playgroud)