浏览器支持的所有HTML标记

时间:2013-08-13 22:18:32

标签: javascript html browser

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

4 个答案:

答案 0 :(得分:5)

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

document.createElement("asdf") instanceof HTMLUnknownElement
true
document.createElement("canvas") instanceof HTMLUnknownElement
false

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

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

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

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

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

答案 1 :(得分:5)

你可以很好地了解窗口内省支持的内容。

试试这个:

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

据我所知,这并非详尽无遗,但它会在大多数浏览器中告诉您哪些标签具有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

答案 2 :(得分:3)

没有一般的方法,但每个元素都有特定的方式来查看它是否支持

Canvas元素支持:

var canvasSupported = "getContext" in document.createElement("canvas");

输入类型支持:

var input = document.createElement("input");
input.type = "color"
var colorInputSupported = input.type === "color";
//The above relies on the fact that type is enumerated and 
//falls back to "text" with invalid value
//The technique doesn't necessarily carry over to other properties

音频元素支持:

var audioElementSupported = "play" in document.createElement("audio");

进度元素支持

var progressElementSupported = "max" in document.createElement("progress");

答案 3 :(得分:3)

document.createElement()创建的每个JavaScript html 元素对象都有一个构造函数,该函数始终以“HTML ...”开头,以“。”结尾。 ..元件”。所有这些都是从HTMLElement继承的。其中每个都可以通过 Object.getOwnPropertyNames()窗口对象中访问。

因此,您可以通过迭代窗口中的所有属性名称来获取所有有效的标记名称,并使用 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;
}

如何使用

console.log(getAllTagNames()); // [anchor", "area", "base", "body", "br", ...]

修改

html元素的一些构造函数只是基本构造函数(例如 HTMLMediaElement )。 在这种情况下, HTMLAudioElement &lt; audio&gt;&lt; / audio&gt; )和 HTMLVideoElement 的基础构造函数(&lt; video&gt ;&lt; / video&gt; )不直接从 HTMLElement 继承。 所以有必要运行完整的原型链, instanceof 运算符适用于此:

window['HTMLAudioElement'].prototype instanceof HTMLElement

另一个方面是某些构造函数名称不适合等效的html标记名称(&lt; a &gt; =&gt; HTML Anchor 元素)和其他一些名称适合多个标签(例如&lt; h1&gt;&lt; / h1&gt;,&lt; h2&gt;&lt; / h2&gt;,&lt; h3&gt;&lt; / h3&gt;,&lt; h4&gt;&lt; / h4&gt;, &lt; h5&gt;&lt; / h5&gt;,&lt; h6&gt;&lt; / h6&gt; )具有相同的构造函数。 > see 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);
}

编辑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" }
];