gpt4 book ai didi

javascript - document.querySelector() 返回一个不是 Node 实例的元素

转载 作者:行者123 更新时间:2023-12-04 08:32:35 26 4
gpt4 key购买 nike

我正在遍历 DOM,我分析的其中一个 div 看起来与其他 div 不同。
所有其他 div:

document.querySelector('#somediv') instanceof Node
// true
但是一个div:
document.querySelector('#strange_div') instanceof Node
// false
当我检查该 div 的构造函数时:
document.querySelector('#strange_div').constructor.name
// HTMLDivElement
然而,当我再次测试 instanceof 时:
document.querySelector('#strange_div') instanceof HTMLDivElement
// false
这怎么可能 ?一个 div 不是 Node 的实例,但它是 HTMLDivElement 的一个实例
备注
div 的类型为 ELEMENT_NODE
   document.querySelector('#strange_div').nodeType
// 1
检查 __proto__
(7) [div#strange, HTMLDivElement, HTMLElement, Element, Node, EventTarget, {…}]
0: div#strange
1: HTMLDivElement {Symbol(Symbol.toStringTag): "HTMLDivElement", constructor: ƒ}
2: HTMLElement {…}
3: Element {…}
4: Node {…}
5: EventTarget {Symbol(Symbol.toStringTag): "EventTarget", addEventListener: ƒ, dispatchEvent: ƒ, removeEventListener: ƒ, constructor: ƒ}
6: {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
比较 中的节点原型(prototype) 链:
document.querySelector('#strange').__proto__.__proto__.__proto__.__proto__ === Node
// false
注2
我的意图是用特定的 getter 函数覆盖 Node 元素。此 getter 可用于所有 div,但不是 Node 实例的。
详细信息: childNodes由一些 3rd 方库扩展,这就是为什么它对我不可用。
我创建了一个新的 iframe,并使用对 childNodes 的纯引用来扩展 Node 元素。 setter/getter
const ref =
Object.getOwnPropertyDescriptor(
safeReferenceFromIframe.Node.prototype,
functionName
) || {};
Object.defineProperty(Node.prototype, `pure_${functionName}`, ref);

最佳答案

How is this possible?


我无法确切知道为什么会发生这种情况,但是 instanceof 是一个众所周知的陷阱。是它不能跨帧工作。 Node在一帧中不同于 Node在另一个框架中。您页面的 DOM 可以包含在另一个框架中创建的元素,如果您使用 instanceof在它上面,它不会继承 Node在您的页面中。
像这样:
const ifr = document.querySelector('iframe');

// Create an <a> element using an iframe's content document
const createdA = ifr.contentDocument.createElement('a');
createdA.textContent = "I am a link";
createdA.href = "http://www.yahoo.com";

// append it to the dom
document.body.appendChild(createdA);

// re-retrieve it
const myA = document.querySelector('a');

console.log('myA instanceof Node', myA instanceof Node); // false
console.log(myA.nodeName); // A
听起来你在一个非常困惑的环境中工作 - .childNodes访问器被覆盖,不继承自 Node 的神秘元素.
我的主要建议是找到一种解决方法。
如果这不是一个选项,我的下一个建议是放弃修改 Node 的尝试。原型(prototype),而是创建一个提供内置 childNodes 功能的函数属性(property)。
看起来可以调整您当前的方法来做到这一点:
// Converts a prototype method to a function that takes an instance
// of that type as the first argument, followed by any additional arguments
const unbind = (f) => (that, ...args) => f.apply(that, args);


const childNodesDesc =
Object.getOwnPropertyDescriptor(
ifr.contentWindow.Node.prototype,
'childNodes'
);


const childNodes = unbind(childNodesDesc.get);


// use childNodes
console.log(childNodes(strangeDiv));

关于javascript - document.querySelector() 返回一个不是 Node 实例的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64951937/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com