2013-08-13 10 views
9

Sử dụng JavaScript, có thể lấy danh sách các thẻ mà trình duyệt hỗ trợ không?Tất cả các thẻ HTML được hỗ trợ bởi Trình duyệt

+1

nó sẽ được sử dụng để làm gì? – twinlakes

+5

@programminginallston Để khắc phục sự tò mò của OP. Hy vọng rằng OP không phải là một con mèo ... – dc5

+0

Tôi không thấy trường hợp sử dụng hợp lệ cho việc này. Bạn có thể giải thích bạn hy vọng đạt được điều gì không? –

Trả lời

4

Bạn có thể có được một ý tưởng khá về những gì đang được hỗ trợ bởi mẫn trên cửa sổ.

Hãy thử điều này:

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

Đây là không có cách nào thấu đáo như xa như tôi biết, nhưng nó sẽ cho bạn biết trong hầu hết các trình duyệt gì thẻ có một loại đối tượng DOM.

Dưới đây là mẫu đầu ra bằng cách chạy này trong giao diện điều khiển Chrome của tôi:

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

Điều này thật thú vị, nhưng nó đưa ra một danh sách các giao diện, không phải danh sách các loại phần tử. Ví dụ, danh sách không chứa bất kỳ thứ gì tương ứng với 'strong' hoặc' span', bởi vì các phần tử này không có giao diện riêng của chúng (chúng chỉ sử dụng giao diện HTMLElement chung). –

+0

Đối với những gì tôi có thể thấy, có lẽ không phải là một cách đáng tin cậy để làm điều đó, nhưng tôi thích phương pháp này vì nó có thể được sử dụng mà không có danh sách bắt đầu và, như @ JukkaK.Korpela nói, sẽ có lỗ trong danh sách, vẫn là một phương pháp khá hay. – Hugo

5

Nếu bạn sẵn sàng để bắt đầu với một danh sách nổi tiếng của các thẻ ứng cử viên, bạn có thể thử một cái gì đó như thế này:

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

Nếu bạn cần hỗ trợ IE8, bạn có thể sử dụng phương pháp này:

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

Đây là một cách tiếp cận khác không phụ thuộc vào các nhà thầu có tên cụ thể.

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

Dường như vẫn không hoạt động trong IE8.

+1

Điều này không hề mạnh mẽ vì các trình duyệt cũ không nhận ra 'HTMLUnknownElement'. Và thử nghiệm theo cách này với IE 10 ở chế độ IE 8, tôi nhận được kết quả 'false' nếu tôi kiểm tra hỗ trợ cho * bất kỳ phần tử * nào (bao gồm cả các phần tử được hỗ trợ chắc chắn, như' p'). –

+0

@ JukkaK.Korpela: Tốt. Tôi đã thêm một triển khai mới xử lý IE8. – recursive

+0

Ý tưởng ban đầu của tôi là không sử dụng thẻ danh sách để bắt đầu nhưng đây cũng là một cách tiếp cận khá thú vị =). – Hugo

3

Không có cách nào chung nhưng mỗi phần tử có cách cụ thể để xem nếu nó được hỗ trợ

Canvas yếu tố hỗ trợ:

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

loại Input hỗ trợ:

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 

hỗ trợ yếu tố âm thanh:

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

Tiến hỗ trợ yếu tố

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

Điều này thực sự là yếu tố cụ thể. Ví dụ, kỹ thuật được sử dụng để hỗ trợ kiểu 'input' thất bại nếu bạn cố gắng áp dụng nó để kiểm tra sự hỗ trợ cho' align = char' cho 'td' (kết quả là đúng, mặc dù không có trình duyệt nào thực sự hỗ trợ giá trị này). –

+0

@ JukkaK.Korpela Đúng vậy, tôi không ngụ ý rằng kỹ thuật kiểm tra kiểu 'đầu vào' chuyển sang bất cứ thứ gì khác. Nó đặc biệt hoạt động vì 'type' là một thuộc tính liệt kê. Tôi đã làm rõ điều này trong một bản chỉnh sửa. – Esailija

+0

Thuộc tính 'align' cũng được liệt kê. Ngay cả các thuộc tính chính thức tương tự (với một danh sách liệt kê các giá trị) có thể được xử lý khác nhau bởi một trình duyệt. –

0

Mỗi Javascript html đối tượng phần tử, được tạo ra bởi document.createElement(), có một hàm constructor mà luôn luôn bắt đầu với " HTML ... "và kết thúc bằng" ... Phần tử ". Tất cả những điều này được kế thừa từ HTMLElement. Mỗi trong số này có thể truy cập trong các đối tượng thông qua Object.getOwnPropertyNames().

Vì vậy, bạn có thể nhận tất cả các tên thẻ hợp lệ bằng cách lặp qua tất cả tên thuộc tính trong cửa sổ và lọc chúng bằng HTML ...Yếu tố:

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; 
} 

Làm thế nào để sử dụng nó:

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

chỉnh sửa

Một số chức năng xây dựng cho các yếu tố html là hàm constructor chỉ cơ sở (ví dụ HTMLMediaElement). Trong trường hợp này hàm xây dựng cơ sở của HTMLAudioElement (< âm thanh > </audio >) và HTMLVideoElement (< video> </video >) không kế thừa trực tiếp từ phần tử html. Vì vậy, nó là cần thiết để chạy qua chuỗi trươc khi hoàn tất, instanceof điều hành là phù hợp cho việc này:

window['HTMLAudioElement'].prototype instanceof HTMLElement 

khía cạnh khác là một số tên hàm constructor phù hợp không để tên thẻ html tương đương (< một > => HTML Neo Element) và một số tên khác phù hợp với một số thẻ (ví dụ < h1 > </h1 >, < h2 > </h2 >, < h3 > </h3 >, < h4 > </h4 >, < h5 > </h5 >, < h6 > </h6 >) với chức năng xây dựng tương tự. > see mdn.

Hiện nay không có cách nào khác trong javscript để tạo ra các tên thẻ được xác định là sai với document.createElement (tagname) ;, kiểm tra xem các nhà xây dựng là một HTMLUnknownElement và cố định những bằng tay:

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); 
} 

chỉnh sửa 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" } 
];