前言
在对接3D可视化的时候,只要页面发生变化,回调就失效了,所以要监听页面变化,添加回调事件。
监听路由变化
这种方式只有路由发生变化后才调用,更合适一点,但是要注意页面加载完毕。
这种方式有时依旧会出现注册的事件消失的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const originalPushState = history.pushState const originalReplaceState = history.replaceState
async function handleRouteChange() { console.log('路由变化:', window.location.href) await new Promise((resolve) => setTimeout(resolve, 100)) pageChange() }
history.pushState = function (...args) { originalPushState.apply(history, args) handleRouteChange() }
history.replaceState = function (...args) { originalReplaceState.apply(history, args) handleRouteChange() }
window.addEventListener('popstate', handleRouteChange)
|
监听页面变化
这种方式页面只要有微小的变动就会触发回调,触发频率较高,并且比较浪费性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| document.addEventListener('DOMContentLoaded', function () { const observer = new MutationObserver(function (mutations, observer) { if (mutations[0].target.innerHTML !== mutations[0].oldValue) { pageChange() } })
const body = document.querySelector('body') if (body) { const config = { childList: true, attributes: true, subtree: true, attributeOldValue: true } observer.observe(body, config) } })
|
注意
直接观察 body 并开启 subtree: true 通常会比较浪费性能,尤其是在复杂页面或动态内容较多的场景下。
定时任务
在对接3D可视化的时候,厂家给的方式是监听body,进行事件的添加,但是这样性能非常不好,监听DOM的性能浪费要比定时任务大多了。
所以最终使用定时任务来实现。
1 2 3 4 5 6 7 8 9 10 11 12
| function addUeListener() { if (window.ueInter) { clearInterval(window.ueInter) } window.ueInter = setInterval(() => { pageChange() }, 2000) }
document.addEventListener('DOMContentLoaded', function () { addUeListener() })
|
最终方案
上面的定时任务可以,但是会一直浪费性能,经测试发现,三维可视化就算我们页面加载后的事件中注入事件依旧会出现事件被清空的情况,应该是页面加载后,可视化又做了一定的操作,等可视化操作结束后,我们添加的回调才不会被清空,所以这里使用了5次尝试,等页面加载后尝试5次就不再尝试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| async function pageChange () { console.info('pageChange') if (window.ue && window.ue.interface) { window.inUe = true
let count = 0 while (count <= 5) { addUeCb() await new Promise((resolve) => setTimeout(resolve, 1000)) count++ } } else { window.inUe = false } }
|
页面组件中
1 2 3 4
| onMounted(async () => { await new Promise((resolve) => setTimeout(resolve, 1000)) window.pageChange() })
|