นี่คือสิ่งที่ฉันคิดออก:
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
มันทดสอบว่า el เป็นตัวอย่างของการสร้างแรงกระตุ้นที่อ้างว่าเป็นหรือไม่ ในการทำเช่นนั้นเราจำเป็นต้องเข้าถึงตัวสร้างโครงสร้างขององค์ประกอบ นั่นเป็นเหตุผลที่เรากำลังทดสอบใน if-Statement ตัวอย่างเช่น IE7 ล้มเหลวเนื่องจาก(document.createElement("a")).constructor
อยู่undefined
ใน IE7
ปัญหาของวิธีนี้document.createElement
คือไม่ใช่ฟังก์ชั่นที่เร็วที่สุดและอาจทำให้แอปพลิเคชั่นของคุณช้าลงหากคุณกำลังทดสอบองค์ประกอบจำนวนมากด้วย เพื่อแก้ปัญหานี้ฉันตัดสินใจแคชสิ่งก่อสร้าง วัตถุElementConstructors
มี nodeNames เป็นคีย์ที่มีตัวสร้างที่สอดคล้องกันเป็นค่า หากตัวสร้างถูกแคชไว้แล้วมันจะใช้มันจากแคชมิฉะนั้นมันจะสร้างองค์ประกอบแคชตัวสร้างของมันสำหรับการเข้าถึงในอนาคตและจากนั้นทดสอบกับมัน
การทดสอบที่สามคือทางเลือกที่ไม่พึงประสงค์ มันทดสอบว่า el เป็นobject
, มีnodeType
คุณสมบัติที่ตั้งไว้1
และสตริงเป็นnodeName
และสตริงแน่นอนว่ามันไม่น่าเชื่อถือ แต่ผู้ใช้ส่วนใหญ่ไม่ควรถอยกลับไปเลย
นี่เป็นวิธีที่น่าเชื่อถือที่สุดที่ฉันคิดขึ้นมาในขณะที่ยังคงประสิทธิภาพไว้สูงที่สุดเท่าที่จะทำได้