tvv*_*old 5 javascript dom-events single-page-application
当单页应用程序上的 DOM 就绪或页面视图发生更改时,我需要触发一个函数,这是我的代码,它在用户第一次访问该网站(DOM 就绪)时工作,但当用户第一次访问该站点时它不起作用切换 SPA 页面(视图已更改)。
我需要一个适用于大多数网站和 SPA 项目的通用方法,因为此代码需要在我们每个客户的网站上执行(有点像 Google Analytics 跟踪代码),并且每次最终用户加载或切换网站时都需要执行此代码页。是否有任何纯 Javascript 可以检测 SPA 何时更改页面?
function docReady(fn) {
if (document.readyState === "complete" || document.readyState === "interactive") {
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
docReady(function() {
_AcodeInit();
});
function _AcodeInit()
{
...
}
Run Code Online (Sandbox Code Playgroud)
选项 1:监听 URL 的变化
由于 SPA 使用路由,因此您可以理想地侦听 url 更改。
一种粗略的方法是使用 setInterval 持续轮询并跟踪 url 的更改。如果 url 已更改,您可以运行您的处理程序。然而,这是浪费的。
由于缺少选项,您可以监听所有可能导致转换的事件(例如鼠标单击、键盘 Enter/Space 键按下等),并在处理程序中检查 url 是否已更改。使用 requestAnimationFrame 以便我们不会过早执行处理程序。
let currentUrl = location.href;
const checkPageTransition = () => {
requestAnimationFrame(() => {
if (currentUrl !== location.href) {
console.log("url changed");
}
currentUrl = location.href;
}, true);
};
document.body.addEventListener("click", checkPageTransition);
document.body.addEventListener("keyup", e => {
if (e.code === "Enter" || e.code === "Space") checkPageTransition()
});
Run Code Online (Sandbox Code Playgroud)
选项2:监听popstate事件
如果您使用现代 SPA,它们很可能会使用history.pushState 和history.popState 来管理路由。然后我们可以监听 window.popstate 事件。但本次活动也有局限性。
来自: https: //developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate
注意:调用history.pushState()或history.replaceState()不会触发popstate事件。popstate 事件仅通过执行浏览器操作来触发,例如在同一文档的两个历史记录条目之间导航时单击后退按钮(或在 JavaScript 中调用history.back())。
然而,我们可以猴子修补history.pushState函数,以便它始终触发history.onpushstate函数。
(function(history) {
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function")
{
history.onpushstate({
state: state
});
}
return pushState.apply(history, arguments);
}
})(window.history);
Run Code Online (Sandbox Code Playgroud)
您还需要类似地修补replaceState 函数。
| 归档时间: |
|
| 查看次数: |
3118 次 |
| 最近记录: |