脚本插入单页面应用(SPA)网站的解决措施

给一些网站写脚本时,有时会遇到该网站是SPA的情况,导致页面内容变化时,脚本察觉不到,针对这种情况可以按如下方法解决:

我想最先想到方法就是监听hashchange事件或者重写pushState方法,这确实是一种措施,但前者只适用于用hash模式实现SPA的网站,但这种网站见的不是很多(至少笔者很少看到过),出于美观考虑,大部分网站都是用History的api来实现SPA的,也就是后者。但后者并不一定每次都能成功,这就是接下来本文主要想写的东西,对于那些是用Historyapi实现的SPA,当重写pushState也不奏效的时候该怎么办。

重写pushState不奏效的原因

在介绍这种情况怎么监听页面变化之前,我想先探讨一下为什么重写pushState也不会奏效。我推测应该是有的网站用的框架,在框架初始化的时候就拿到了History相关api的引用,所以脚本插入时再重写pushState的时候就已经迟了,因为网站已经有了pushState的备份,不会受到你脚本重写的影响了。当然这也只是我的猜测,欢迎评论区中讨论具体原因。

MutationObserver和baseURI

对于重写pushState也不奏效的网站,可以考虑使用MutationObserver,它是原生的js工具,用于检测页面DOM变化。因为SPA即使不会重载document了,但肯定也会涉及到DOM变化,这样我们就可以监听DOM变化,然后查看变化后的元素的baseURI,来判断当前网页是否变化了。

参考如下代码:

const callback = (records)=>{
    
    
        //逻辑代码写在这
    }
const observer = new MutationObserver(callback)
observer.observe(document.body, {
    
    
	//选项设置,这是只是举例说明
   	childList: true, //是否监听子代元素变化(新增,删除或者更改)
   	subtree: true //是否监听目标元素的所有后代元素
})

MutationObserver用法
baseURI用法

其它

其实我最开始是想用Object.defineProperty直接监听Historystate属性的,结果发现pushState之类方法改变state的时候并不会调用到statesetter方法。之后还试了直接监听HistoryLocation,但发现这两个属性不能被重新定义了。这些都是浏览器的内部代码,也就不好深入了。

参考连接:
脚本仅在从后端加载过来的页面有用,而在前端生成的页面就没用了?

猜你喜欢

转载自blog.csdn.net/weixin_55658418/article/details/128909714
今日推荐