document.adoptNode & document.importNode & node.ownerDocument All In One
document.adoptNode & document.importNode & node.ownerDocument All In One
将外部文档的节点插入当前文档之前,你必须使用 document.importNode() 从外部文档导入源节点,或者使用 document.adoptNode() 导入源节点
注意事项
注意: 使用 adoptNode() 方法从一个外部文档中获取一个节点, 节点下的所有子节点都会获取到, 拷贝后在外部文档中的节点及其子节点会被删除。
注意: 使用 document.importNode() 方法从外部文档中来拷贝节点,拷贝后在外部文档中的节点不会被删除。
注意: 使用 node.cloneNode() 方法从当前文档中来拷贝节点,拷贝后在当前文档中的节点不会被删除。
https://iframe.xgqfrms.xyz/dom-api/iframe.html
https://iframe.xgqfrms.xyz/dom-api/adoptNode.html
https://iframe.xgqfrms.xyz/dom-api/importNode.html
https://iframe.xgqfrms.xyz/dom-api/cloneNode.html
document.adoptNode
adoptNode(externalNode)
  const adoptNode = () => {
    // const frame = document.getElementsByTagName("iframe")[0];
    // const h1 = frame.contentWindow.document.getElementsByTagName("h1")[0];
    const frame = document.querySelector('#iframe');
    // const h1 = frame.contentWindow.document.querySelector("h1");
    const h1 = iframe.contentDocument.querySelector("h1");
    // ✅ deep = false 不包含 text
    // const dom = document.adoptNode(h1);
    // const dom = document.adoptNode(h1, false);
    // 从 iframe 文档中提取出 DOM tree,并从 iframe 文档中删除该 DOM tree
    const dom = document.adoptNode(h1, true);
    // 把 DOM tree 添加到当前文档中
    // document.body.appendChild(dom);
    const app = document.querySelector(`#app`);
    app.appendChild(dom);
  };
https://developer.mozilla.org/en-US/docs/Web/API/Document/adoptNode
document.importNode
importNode(externalNode)
importNode(externalNode, deep)
<iframe id="iframe" src="https://iframe.xgqfrms.xyz/webview-checker/index.html"></iframe>
<div id="app">App</app>
  // iframe CORS limit ⚠️
  const importNode = () => {
    // const iframe = document.getElementsByTagName("iframe")[0];
    // const h1 = iframe.contentWindow.document.getElementsByTagName("h1")[0];
    const iframe = document.querySelector('#iframe');
    // const h1 = iframe.contentWindow.document.querySelector("h1");
    const h1 = iframe.contentDocument.querySelector("h1");
    // 从 iframe 文档中提取出 DOM tree
    // ✅ deep = false 不包含 text
    // const dom = document.importNode(h1);
    // const dom = document.importNode(h1, false);
    const dom = document.importNode(h1, true);
    // 把 DOM tree 添加到当前文档中
    // document.body.appendChild(dom);
    const app = document.querySelector(`#app`);
    app.appendChild(dom);
  };
CORS
https://cdn.xgqfrms.xyz/iframe/same-origin-iframe.html ✅
https://cdn.xgqfrms.xyz/iframe/iframe-single-testing.html ❌
const iframe = document.querySelector(`#iframe`);
const externalNode = iframe. contentDocument.querySelector(`[data-dom="pre"]`);
// document.querySelector(`[data-dom="pre"]`);
const app = document.querySelector(`#app`);
// only clone tree
// const newApp = aapp.importNode(externalNode, false);
// clone both tree and subtree
const newApp = app.importNode(externalNode, true);
// node.appendChild() 
document.body.appendChild(newApp);
https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode
node.cloneNode
⚠️ Warning: cloneNode() may lead to
duplicate element IDsin a document!
cloneNode();
cloneNode(deep);
<div id="app">App</app>
const app = document.querySelector(`#app`);
// only clone tree
// const newApp = app.cloneNode(false);
// clone both tree and subtree
const newApp = app.cloneNode(true);
// node.appendChild() 
document.body.appendChild(newApp);
https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode
node.ownerDocument
如果在本身是文档的节点上使用此属性,则值为 null
// Given a node "div", get the top-level HTML child of the document object
const div = document.querySelector('div');
const documentRoot = div.ownerDocument;
// #document
const html = documentRoot.documentElement;
// <html>...</html>

// document self object ❓iframe
const dom = document.querySelector('html');
const documentRoot = dom.ownerDocument;
// <html>...</html> ✅
// null ❌
// document self object
document;
// #document
document.ownerDocument;
// null ✅

https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument
Web Components
adoptedCallback
class MyElement extends HTMLElement {
  constructor() {
    super();
    // 元素在这里创建
  }
  connectedCallback() {
    // 在元素被添加到文档之后,浏览器会调用这个方法
    //(如果一个元素被反复添加到文档/移除文档,那么这个方法会被多次调用)
  }
  disconnectedCallback() {
    // 在元素从文档移除的时候,浏览器会调用这个方法
    // (如果一个元素被反复添加到文档/移除文档,那么这个方法会被多次调用)
  }
  static get observedAttributes() {
    return [/* 属性数组,这些属性的变化会被监视 */];
  }
  attributeChangedCallback(name, oldValue, newValue) {
    // 当上面数组中的属性发生变化的时候,这个方法会被调用
  }
  adoptedCallback() {
    // 在元素被移动到新的文档的时候,这个方法会被调用
    // (document.adoptNode 会用到, 非常少见)
  }
  // 还可以添加更多的元素方法和属性
}
https://zh.javascript.info/custom-elements
refs
https://github.com/mdn/content/pull/18005
https://developer.mozilla.org/en-US/docs/Web/API/Node
https://developer.mozilla.org/en-US/docs/DOM/document
iframe &
contentDocument&contentWindow
https://www.cnblogs.com/xgqfrms/p/10312189.html
https://github.com/xgqfrms/iframe/tree/master/dom-api
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16449386.html
未经授权禁止转载,违者必究!

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号