Skip to content

Instantly share code, notes, and snippets.

@zhoukekestar
Last active April 19, 2024 11:46
Show Gist options
  • Save zhoukekestar/21788dc4dda81832e91ba34421e69426 to your computer and use it in GitHub Desktop.
Save zhoukekestar/21788dc4dda81832e91ba34421e69426 to your computer and use it in GitHub Desktop.
wujie WebComponent plugin
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')
// 对那些自定义元素进行 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