यह वही है जो मैंने सोचा था:
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";
}
}
})();
प्रदर्शन में सुधार करने के लिए मैंने एक आत्म-आविष्कारक फ़ंक्शन बनाया जो केवल एक बार ब्राउज़र की क्षमताओं का परीक्षण करता है और तदनुसार उचित फ़ंक्शन असाइन करता है।
पहला परीक्षण अधिकांश आधुनिक ब्राउज़रों में काम करना चाहिए और पहले से ही यहां चर्चा की गई थी। यह सिर्फ परीक्षण करता है कि तत्व किसका उदाहरण हैHTMLElement
। बहुत सीधा है।
दूसरा सबसे दिलचस्प एक है। यह इसकी मुख्य कार्यक्षमता है:
return el instanceof (document.createElement(el.nodeName)).constructor
यह परीक्षण करता है कि क्या एल इस बाधा का एक उदाहरण है कि यह होने का दिखावा करता है। ऐसा करने के लिए, हमें किसी तत्व के अवरोधक तक पहुंच की आवश्यकता है। इसलिए हम इफ-स्टेटमेंट में इसका परीक्षण कर रहे हैं। उदाहरण के लिए IE7 इस विफल रहता है, क्योंकि (document.createElement("a")).constructor
है undefined
IE7 में।
इस दृष्टिकोण के साथ समस्या यह है कि document.createElement
वास्तव में सबसे तेज़ कार्य नहीं है और यदि आप इसके साथ बहुत सारे तत्वों का परीक्षण कर रहे हैं तो आसानी से आपके आवेदन को धीमा कर सकते हैं। इसे हल करने के लिए, मैंने कंस्ट्रक्टर्स को कैश करने का फैसला किया। ऑब्जेक्ट ElementConstructors
में मानों के रूप में उसके संबंधित कंस्ट्रक्टरों के साथ नोडनेम होते हैं। यदि कोई कंस्ट्रक्टर पहले से कैश है, तो वह इसे कैशे से उपयोग करता है, अन्यथा यह एलिमेंट बनाता है, भविष्य के एक्सेस के लिए इसके कंस्ट्रक्टर को कैश करता है और फिर इसके खिलाफ टेस्ट करता है।
तीसरा परीक्षण अप्रिय गिरावट है। यह परीक्षण करता है कि क्या el एक है object
, के पास एक nodeType
संपत्ति है 1
और एक स्ट्रिंग हैnodeName
। यह निश्चित रूप से बहुत विश्वसनीय नहीं है, फिर भी उपयोगकर्ताओं के विशाल बहुमत को अब तक वापस नहीं आना चाहिए।
यह सबसे विश्वसनीय दृष्टिकोण है जिसे मैं अभी भी संभव के रूप में उच्च प्रदर्शन रखते हुए आया था।