이것이 내가 알아 낸 것입니다.
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 문에서 이것을 테스트하는 이유입니다. 예를 들어 IE7에 있기 때문에 IE7 (document.createElement("a")).constructor
은 이것을 실패합니다 undefined
.
이 방법의 문제점 document.createElement
은 실제로 가장 빠른 기능이 아니며 많은 요소를 테스트하는 경우 응용 프로그램 속도를 쉽게 늦출 수 있다는 것입니다. 이를 해결하기 위해 생성자를 캐시하기로 결정했습니다. 객체 ElementConstructors
는 nodeNames를 키로 사용하고 해당 생성자를 값으로 사용합니다. 생성자가 이미 캐시 된 경우 캐시에서 생성자를 사용합니다. 그렇지 않으면 요소를 작성하고 나중에 액세스 할 수 있도록 생성자를 캐시 한 다음 이에 대해 테스트합니다.
세 번째 테스트는 불쾌한 폴백입니다. el이 object
이고 nodeType
속성이로 설정되어 1
있고 문자열이로 설정되어 있는지 테스트합니다 nodeName
. 물론 이것은 신뢰할 만하지는 않지만 대다수의 사용자는 지금까지 다시 넘어서는 안됩니다.
이것은 가능한 한 성능을 계속 유지하면서 내가 찾은 가장 신뢰할만한 접근법입니다.