Backbone.js 防止主干驱动SPA内的页面导航
理由 在我的BB应用程序中,我允许来自用户的快速输入,这些用户在后台定期排队并发送到服务器。我目前遇到的问题是,如果用户离开页面,他们会有效地放弃队列中任何挂起的更改 因此,基本上我想做的是在用户离开之前通知他们,让他们有机会等待更改被保存,而不仅仅是退出和放弃 本质 因此,对于用户刷新或尝试导航到外部URL的一般情况,我们可以处理该事件。当我们处于SPA环境中时,页面之间的切换不会导致页面刷新,这就变得有点棘手了 我的直接想法是对所有锚使用全局单击事件处理程序,并验证是否允许单击,这将适用于站点内链接导航。然而,这是通过浏览器的后退/前进按钮进行导航 我还看了一眼,乍一看,它似乎正是我所需要的。但是,使用中描述的简单案例,路由仍在执行中 问题Backbone.js 防止主干驱动SPA内的页面导航,backbone.js,browser-history,pushstate,backbone-routing,Backbone.js,Browser History,Pushstate,Backbone Routing,理由 在我的BB应用程序中,我允许来自用户的快速输入,这些用户在后台定期排队并发送到服务器。我目前遇到的问题是,如果用户离开页面,他们会有效地放弃队列中任何挂起的更改 因此,基本上我想做的是在用户离开之前通知他们,让他们有机会等待更改被保存,而不仅仅是退出和放弃 本质 因此,对于用户刷新或尝试导航到外部URL的一般情况,我们可以处理该事件。当我们处于SPA环境中时,页面之间的切换不会导致页面刷新,这就变得有点棘手了 我的直接想法是对所有锚使用全局单击事件处理程序,并验证是否允许单击,这将适用于站
如何在主干SPA中拦截所有场景的导航?直接链接导航 使用全局事件处理程序捕获所有单击事件
$(document).on('click', 'a[href^="/"]', function (e) {
var href = $(e.currentTarget).attr('href');
e.preventDefault();
if (doSomeValidation()) {
router.navigate(href, { trigger: true });
}
});
页面刷新/外部URL导航
在窗口上处理onbeforeuload
事件
$(window).on('beforeunload', function (e) {
if (!doSomeValidation()) {
return 'Leaving now will may result in data loss';
}
});
浏览器后退/前进按钮导航
幕后使用最终利用的。根据您传递给的选项以及浏览器的功能,API将挂接到onhashchange
事件或onpopstate
事件
深入研究主干.history.start的源代码很明显,无论您是否使用push state,都会使用相同的事件处理程序,即
因此,我们可以重写此方法并在其中执行验证
var originalCheckUrl = Backbone.history.checkUrl;
Backbone.history.checkUrl = function (e) {
if (doSomeValidation()) {
return originalCheckUrl.call(this, e);
} else {
// re-push the current page into the history (at this stage it's been popped)
window.history.pushState({}, document.title, Backbone.history.fragment);
// cancel the original event
return false;
}
};
var originalCheckUrl = Backbone.history.checkUrl;
Backbone.history.checkUrl = function (e) {
if (doSomeValidation()) {
return originalCheckUrl.call(this, e);
} else {
// re-push the current page into the history (at this stage it's been popped)
window.history.pushState({}, document.title, Backbone.history.fragment);
// cancel the original event
return false;
}
};