JavaScript中能否将iframe的document对象赋值给全局document变量?赋值后元素查询失效的原因是什么?
Hey there! Let's break down why your e2 example isn't working, and how you can achieve your goal of using a global reference for the iframe's document.
Why document = iframeDoc doesn't work
The global document object (which is actually window.document under the hood) is a core browser-hosted property that's non-writable and non-configurable. You can confirm this yourself in the browser console:
Object.getOwnPropertyDescriptor(window, 'document')
The result will show writable: false and configurable: false. What this means for your code:
- In non-strict mode (which your code is using), the assignment
document = iframeDocgets silently ignored by the browser. The globaldocumentstill points to your main page's document, not the iframe's. - If you ran this in strict mode (with
'use strict'at the top), it would throw a clear error:TypeError: Assignment to read-only property 'document' of object '#<Window>'
That's exactly why your e2 query returns null — you're still searching the main page's document, not the iframe's content.
What you can do instead (global reference without passing variables)
Since you can't overwrite the native document, here are two clean ways to get a global reference to the iframe's document, just like you wanted:
1. Create a custom global alias
Define your own global variable to hold the iframe's document. Use globalThis (the standard, environment-agnostic way to access the global scope) to ensure it's available everywhere in your code:
// Store the iframe document in a global alias globalThis.iframeDoc = iframeDoc; // Now use this alias anywhere without passing context const e2 = iframeDoc.evaluate("id('shadow_host')", iframeDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; console.log(`e2=${e2}`); // Will log [object HTMLDivElement]
2. Wrap queries in a global function
If you want to avoid even typing a different variable name, create a global function that uses the iframe's document internally:
// Store the iframe document once const targetDoc = iframeDoc; // Global function to run queries against the iframe globalThis.queryIframe = function(selector) { return targetDoc.evaluate(selector, targetDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }; // Use it anywhere with a clean, consistent call const e2 = queryIframe("id('shadow_host')"); console.log(`e2=${e2}`);
Recap
- You can't overwrite the native
documentobject — browser security and core API design prevent this. - Your
e1works because you're directly using the iframe's document, whilee2fails becausedocumentstill points to the main page. - Use a custom global variable or wrapper function to get the "global context" you need without fighting the browser's built-in APIs.
备注:内容来源于stack exchange,提问作者oldpride

