Inilah yang saya tahu:
var isHTMLElement = (function () {
if ("HTMLElement" in window) {
// Voilà. Quick and easy. And reliable.
return function (el) {return el instanceof HTMLElement;};
} else if ((document.createElement("a")).constructor) {
// We can access an element's constructor. So, this is not IE7
var ElementConstructors = {}, nodeName;
return function (el) {
return el && typeof el.nodeName === "string" &&
(el instanceof ((nodeName = el.nodeName.toLowerCase()) in ElementConstructors
? ElementConstructors[nodeName]
: (ElementConstructors[nodeName] = (document.createElement(nodeName)).constructor)))
}
} else {
// Not that reliable, but we don't seem to have another choice. Probably IE7
return function (el) {
return typeof el === "object" && el.nodeType === 1 && typeof el.nodeName === "string";
}
}
})();
Untuk meningkatkan kinerja, saya membuat fungsi self-invaging yang menguji kemampuan browser hanya sekali dan menetapkan fungsi yang sesuai.
Tes pertama harus bekerja di sebagian besar browser modern dan sudah dibahas di sini. Itu hanya menguji apakah elemen tersebut adalah instance dari HTMLElement
. Sangat mudah.
Yang kedua adalah yang paling menarik. Ini adalah fungsionalitas intinya:
return el instanceof (document.createElement(el.nodeName)).constructor
Ia menguji apakah el adalah turunan dari konstruktor yang dikehendaki. Untuk melakukan itu, kita perlu akses ke konstruktor elemen. Itu sebabnya kami menguji ini di if-Statement. IE7 misalnya gagal ini, karena (document.createElement("a")).constructor
ada undefined
di IE7.
Masalah dengan pendekatan ini adalah yang document.createElement
benar-benar bukan fungsi tercepat dan dapat dengan mudah memperlambat aplikasi Anda jika Anda menguji banyak elemen dengannya. Untuk mengatasi ini, saya memutuskan untuk membuat cache konstruktor. Objek ElementConstructors
memiliki nodeNames sebagai kunci dengan konstruktor yang sesuai sebagai nilai. Jika sebuah konstruktor sudah di-cache, ia menggunakannya dari cache, jika tidak ia menciptakan Elemen, cache konstruktornya untuk akses di masa depan dan kemudian mengujinya.
Tes ketiga adalah fallback yang tidak menyenangkan. Ia menguji apakah el adalah sebuah object
, memiliki nodeType
properti yang disetel 1
dan string sebagai nodeName
. Ini tentu saja tidak terlalu andal, namun sebagian besar pengguna seharusnya tidak mundur sejauh ini.
Ini adalah pendekatan yang paling dapat diandalkan yang saya buat dengan tetap menjaga kinerja setinggi mungkin.