如果我想检查特定的 DOM 节点是否是锚元素,哪个选项会更安全、更快?
通过更安全,我正在寻找较旧的浏览器(例如 IE6-8)更好地支持哪个。
我假设速度不会有太大差异,但如果一个函数在遍历 DOM 树时执行此检查,可能会节省几毫秒。
tagName
和instanceof
在我出生之前就得到了支持。
使用
tagName
比instanceof
稍快,因为它不需要检查原型链。
如果您使用像 TypeScript 这样的类型检查器, 有时使用
instanceof
更好,因为您可以利用 类型缩小。
例如:
document.addEventListener('click', (e) => {
if (e.defaultPrevented) return;
const target = e.target; // Here the type is EventTarget, and target.href is not a known member.
if (
target instanceof HTMLAnchorElement &&
target.href && // Here the type is HTMLAnchorElement, avoiding a type error.
target.target === '_blank'
) {
// The type is narrowed to HTMLAnchorElement inside the condition body as well.
e.preventDefault();
discordSdk.commands.openExternalLink({ url: target.href });
}
});
如果使用
tagName
,类型检查器会抱怨未知属性 href
和 target
。
此外,使用
tagName
,更容易犯错误,例如忘记将标签名称大写或拼写错误,
而使用类的名称,类型检查器可以验证它是否存在。
如果您使用
iframe
元素,并通过 contentWindow
或 contentDocument
访问其中的元素,
instanceof
可能无法按预期工作,因为每个框架都有自己的 DOM 对象类版本,例如 HTMLAnchorElement
。
尝试在任何页面的控制台中运行此代码:
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentDocument.write('<a href="https://example.com" target="_blank">Click me</a>');
iframe.contentDocument.close();
const anchor = iframe.contentDocument.querySelector('a');
console.log("A)", anchor.tagName === 'A'); // true
console.log("B)", anchor instanceof HTMLAnchorElement); // false
console.log("C)", anchor instanceof iframe.contentWindow.HTMLAnchorElement); // true
在这种情况下,使用
instanceof
的正确代码是使用 tagName
的两倍多。
更多示例:
iframe.contentWindow.isItAnAnchor1 = (el) => el instanceof HTMLAnchorElement;
iframe.contentWindow.isItAnAnchor2 = function(el) { return el instanceof HTMLAnchorElement; };
iframe.contentWindow.isItAnAnchor3 = function(el) { return el instanceof self.HTMLAnchorElement; };
iframe.contentWindow.isItAnAnchor4 = (el)=> el instanceof this.HTMLAnchorElement;
iframe.contentWindow.isItAnAnchor5 = function(el) { return el instanceof this.HTMLAnchorElement; };
console.log("D)", iframe.contentWindow.isItAnAnchor1(anchor)); // false, because `HTMLAnchorElement` refers to the parent window's version
console.log("E)", iframe.contentWindow.isItAnAnchor2(anchor)); // false, because `HTMLAnchorElement` refers to the parent window's version
console.log("F)", iframe.contentWindow.isItAnAnchor3(anchor)); // false, because `self` refers to the parent window
console.log("G)", iframe.contentWindow.isItAnAnchor4(anchor)); // false, because `this` refers to the parent window
console.log("H)", iframe.contentWindow.isItAnAnchor5(anchor)); // true, because `this` refers to the iframe's window in this case
使用 javascript,99% 的情况下 proc 资源都不是优先考虑的。 如果您必须检查 tagName,您最好使用显式暴露给您的 tagName。
对我来说,instanceof要长得多,因为你必须检查原型的类型,tagName是一个已经设置的属性。