Ben bunu anladım:
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";
}
}
})();
Performansı artırmak için, tarayıcının yeteneklerini yalnızca bir kez test eden ve buna göre uygun işlevi atayan kendi kendini çağıran bir işlev oluşturdum.
İlk test çoğu modern tarayıcıda çalışmalıdır ve burada zaten tartışılmıştır. Sadece öğenin bir örneği olup olmadığını test eder HTMLElement
. Çok basit.
İkincisi en ilginç olanı. Temel işlevi:
return el instanceof (document.createElement(el.nodeName)).constructor
El'in, varmış gibi görünen yapının bir örneği olup olmadığını test eder. Bunu yapmak için bir elemanın yapıcısına erişmemiz gerekir. Bu yüzden if-Deyiminde bunu test ediyoruz. Çünkü örneğin IE7, bu başarısız (document.createElement("a")).constructor
olduğu undefined
IE7'de.
Bu yaklaşımdaki sorun document.createElement
, gerçekten en hızlı işlev olmaması ve çok sayıda öğeyi test ediyorsanız uygulamanızı yavaşlatabilmesidir. Bunu çözmek için yapıcıları önbelleğe almaya karar verdim. Nesnenin ElementConstructors
anahtarları olarak nodeNames, karşılık gelen kurucuları değer olarak içerir. Bir kurucu zaten önbelleğe alınmışsa, onu önbellekten kullanır, aksi takdirde Öğe'yi oluşturur, yapıcısını gelecekteki erişim için önbelleğe alır ve sonra buna karşı test eder.
Üçüncü test tatsız düşüştür. El'in bir object
, bir nodeType
özelliği 1
ve bir dize olarak ayarlanmış olup olmadığını test eder nodeName
. Bu elbette çok güvenilir değil, ancak kullanıcıların büyük çoğunluğu şimdiye kadar geri çekilmemeli.
Performansı mümkün olduğunca yüksek tutarken ortaya koyduğum en güvenilir yaklaşım budur.