Last active
April 19, 2024 11:46
-
-
Save zhoukekestar/21788dc4dda81832e91ba34421e69426 to your computer and use it in GitHub Desktop.
wujie WebComponent plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { bus, setupApp, preloadApp, startApp, destroyApp } from 'wujie' | |
window.switchApp = name => { | |
startApp({ | |
name, | |
url: | |
name === 'home1' | |
? 'https://systemjs.1688.com/krump/schema/2528.html' | |
: 'https://systemjs.1688.com/krump/schema/2529.html', | |
el: '#root', | |
exec: true, | |
alive: true, | |
plugins: [ | |
{ | |
jsBeforeLoaders: [ | |
{ | |
callback: patchCustomElementBeforeDefine | |
} | |
] | |
} | |
] | |
// sync: true | |
}) | |
} | |
window.switchApp('home1') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 对那些自定义元素进行 patch(在未定义前) | |
function patchCustomElementBeforeDefine (appWindow) { | |
// 对当前 dom 树进行遍历 | |
const document = appWindow.document | |
const window = appWindow | |
const walkTree = (root, name, list) => { | |
const treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ALL) | |
while (treeWalker.nextNode()) { | |
const node = treeWalker.currentNode | |
// 遍历 shadowRoot | |
if (node.shadowRoot) { | |
walkTree(node.shadowRoot, name, list) | |
} | |
// 如果是目标节点 | |
if (node.tagName === name.toUpperCase()) { | |
list.push(node) | |
} | |
} | |
} | |
// 重写 define | |
const define = window.customElements.define | |
window.customElements.define = function (name, constructor, options) { | |
// 执行原生的 define | |
define.call(window.customElements, name, constructor, options) | |
// define 之后的 hook | |
setTimeout(() => { | |
const oldChildList = [] | |
walkTree(document.body, name, oldChildList) | |
// 遍历旧的子节点 | |
oldChildList.forEach(oldChild => { | |
// 如果已经初始化完成的节点,则不做替换 | |
if (oldChild instanceof constructor) return | |
// 否则,替换 | |
const newChild = document.createElement(name) | |
// 老的 lightdom 复制到新的 | |
for (let i = 0 ; i < oldChild.children.length; i++) { | |
const child = oldChild.children[i] | |
newChild.appendChild(child) | |
} | |
// 老的属性复制到新的 | |
for (let i = 0; i < oldChild.attributes.length; i++) { | |
const { name, value } = oldChild.attributes[i] | |
newChild.setAttribute(name, value) | |
} | |
// 替换 | |
oldChild.parentNode.replaceChild(newChild, oldChild) | |
}) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment