我正在开发一个
dash
网络应用程序,它是一个multi
页面应用程序。下面是我的结构
- project/
- pages/
- home.py
- contact.py
- graph.py
- app.py
- index.py
在
app.py
中,我有一个组件 dcc.Location(id="url", refresh=True),
使用回调将不同页面加载到 html.Div(id="page-content")
。当用户单击每个页面都有 navlinks
的侧边栏时,页面已成功加载。
假设我在
home
页面(localhost/home),现在单击转到 contact
页面(localhost/contact),它可以工作。在这里,在离开 home
页面之前,我想将数据保存在 dcc.store
组件中。一种方法是拥有 hidden
按钮并通过 javascript 激活此按钮回调。为此,在 assets
文件夹中,我创建了一个 custom-script.js
document.addEventListener('visibilitychange', e=>{
if (document.visibilityState === 'visible') {
console.log("user is focused on the page")
} else {
// code to trigger button click event to activate callback
console.log("user left the page")
}
});
但我注意到,即使我从
home
页面切换到contact
页面,事件也没有触发。可能是通过回调更新页面内容似乎不会影响刷新(即使设置为 True)。但是如果我通过 home
页面上的浏览器刷新按钮进行硬刷新 事件被触发
还有其他方法可以使用破折号或 JavaScript 来检测页面更改吗?
您可能需要一个破折号回调和自定义脚本:
如果通过“位置”链接导航到应用程序内的页面不会触发
visibilitychange
事件,您仍然可以通过破折号回调更新商店(在 app.py 以及“位置”和“商店”组件中定义) ,例如。
@app.callback(
Output("store-id", "data"),
Input('url', 'pathname'),
State("store-id", "data"),
prevent_initial_call=True,
)
def update_store(pathname, data):
data['someproperty'] = 'some value'
return data
对于用户浏览器刷新页面或转到另一个网站的情况,
visibilitychange
事件应该正确触发。但是,我认为从事件处理程序触发按钮单击并不是最佳选择,因为脚本可能会在按钮单击回调解析(用户离开页面)之前终止,而您可以直接加载/更新 VisibilityChange 处理程序中的存储,例如。
document.addEventListener('visibilitychange', e => {
if (document.visibilityState === 'visible') {
console.log("user is focused on the page");
}
else {
// Update store data
const data = JSON.parse(localStorage.getItem('store-id'));
data.someproperty = 'some value';
localStorage.setItem('store-id', JSON.stringify(data ));
console.log("user left the page");
}
});