Đây là những gì tôi đã tìm ra:
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";
}
}
})();
Để cải thiện hiệu suất, tôi đã tạo một chức năng tự gọi chỉ kiểm tra các khả năng của trình duyệt một lần và chỉ định chức năng phù hợp.
Thử nghiệm đầu tiên sẽ hoạt động trong hầu hết các trình duyệt hiện đại và đã được thảo luận ở đây. Nó chỉ kiểm tra nếu phần tử là một thể hiện của HTMLElement
. Rất đơn giản.
Cái thứ hai là cái thú vị nhất. Đây là chức năng cốt lõi của nó:
return el instanceof (document.createElement(el.nodeName)).constructor
Nó kiểm tra xem el có phải là một thể hiện của hàm tạo không. Để làm điều đó, chúng ta cần truy cập vào phần tử của phần tử. Đó là lý do tại sao chúng tôi đang thử nghiệm điều này trong if-Statement. IE7 ví dụ thất bại này, bởi vì (document.createElement("a")).constructor
là undefined
trong IE7.
Vấn đề với phương pháp này là đó document.createElement
thực sự không phải là chức năng nhanh nhất và có thể dễ dàng làm chậm ứng dụng của bạn nếu bạn đang thử nghiệm nhiều yếu tố với nó. Để giải quyết điều này, tôi quyết định lưu trữ các hàm tạo. Đối tượng ElementConstructors
có nodeNames là các khóa với các hàm tạo tương ứng của nó làm các giá trị. Nếu một hàm tạo đã được lưu vào bộ đệm, nó sẽ sử dụng nó từ bộ đệm, nếu không, nó tạo ra Element, lưu trữ hàm tạo của nó để truy cập trong tương lai và sau đó kiểm tra lại nó.
Thử nghiệm thứ ba là dự phòng khó chịu. Nó kiểm tra xem el là một object
, có một thuộc nodeType
tính được đặt thành 1
và một chuỗi như nodeName
. Tất nhiên điều này không đáng tin cậy lắm, tuy nhiên đại đa số người dùng thậm chí không nên quay lại cho đến nay.
Đây là cách tiếp cận đáng tin cậy nhất mà tôi đã đưa ra trong khi vẫn giữ hiệu suất cao nhất có thể.