我正在尝试使用Backbone的pushState阻止整页重新加载。当我从视图的事件中调用navigate()时,我看到下面标记为// 1但不是// 2的消息。此外,当我尝试打开相同的选项卡时,页面会重新加载。
我必须自己停止活动吗?我尝试使用jQuery的preventDefault(),它确实阻止了页面重新加载,但我没有在任何地方看到过这种情况。
以下是我目前的代码:
App.Router = Backbone.Router.extend({
routes:{
"analytics":"analytics"
, "realtime":"realtime"
}
, analytics:function(page) {
console.log("analytics route hit: %o", page); // 2
}
, realtime:function(page) {
console.log("realtime route hit: %o", page); // 2
}
});
App.TabSetView = Backbone.View.extend({
initialize:function() {
this.collection.bind("reset", this.render, this);
this.collection.bind("add", this.render, this);
this.collection.bind("change", this.render, this);
this.collection.bind("remove", this.render, this);
}
, events:{
'click li.realtime a': "onRealtime"
, 'click li.analytics a': "onAnalytics"
}
, render:function() {
// omitted for brevity
}
, onAnalytics:function() {
console.log("onAnalytics"); // 1
if (this.collection.activateAnalytics()) {
App.app.navigate("analytics", true);
this.render();
console.log("navigated");
} else {
console.log("do nothing"); // 1
}
}
, onRealtime:function() {
console.log("onRealtime");
if (this.collection.activateRealtime()) {
App.app.navigate("realtime", true);
this.render();
console.log("navigated");
} else {
console.log("do nothing"); // 1
}
}
});
var tabs = ...; // omitted for brevity
var tabSetView = new App.TabSetView({collection: tabs});
var App.app = new App.Router;
Backbone.history.start({pushState:true});
答案 0 :(得分:19)
要在用户点击链接时停止重新加载页面,您必须按照建议调用e.preventDefault()
。
MyView = Backbone.View.extend({
events: {
"click .some a": "clicked"
},
clicked: function(e){
e.preventDefault();
// do your stuff here
}
});
你也是对的,骨干文档中没有记录这一点。但事件由jQuery处理。所以你可以假设你要做的任何有效的jQuery事情 - 例如对事件回调有一个e
参数 - 将与骨干的events
一起使用。
至于:
in addition, when I try to open the same tab, the page reloads again.
您是说当用户在您网站的网址上打开新的浏览器标签时?如果是这样,那么你无能为力。当浏览器打开选项卡时,它向服务器发出加载页面的请求。
如果你在网站的用户界面中引用了“标签”,那么在你的链接/“标签”点击上使用e.preventDefault()
就可以解决这个问题。
答案 1 :(得分:19)
答案实际上在这里https://stackoverflow.com/a/9331734/985383,如果您启用pushState,您希望链接工作,而不是像上面建议的那样阻止它们,或者好吧,不仅仅是阻止它们。这是:
initializeRouter: function () {
Backbone.history.start({ pushState: true });
$(document).on('click', 'a:not([data-bypass])', function (evt) {
var href = $(this).attr('href');
var protocol = this.protocol + '//';
if (href.slice(protocol.length) !== protocol) {
evt.preventDefault();
app.router.navigate(href, true);
}
});
}
答案 2 :(得分:5)
$('a').click(function(e){
e.preventDefault();
Backbone.history.navigate(e.target.pathname, {trigger: true});
});
答案 3 :(得分:2)
跟进德里克的回答。 它对我有用,但为了保持干净,我覆盖了Backbone.View类:
(CoffeeScript的)
class NewBackboneView extends Backbone.View
events:
'click a' : 'pushstateClick'
pushstateClick: (event) ->
event.preventDefault()
Backbone.View = NewBackboneView
因此,我的骨干视图中的每个链接都具有防止默认值。
答案 4 :(得分:0)
这取决于您如何生成HTML标记。看起来您正在使用锚标记(<a>
),因此如果这些锚标记href具有值或甚至是空字符串,那么您需要取消默认的浏览器行为,否则您将获得页面重新加载。你可以像你提到的那样使用jQuery're event.preventDefault()来取消默认行为。或者,如果您不关心渐进增强或SEO,那么您可以将锚标记href设置为#或javascript:void(0);,这也将阻止页面重新加载。 e.g。
<a href="#">Click me</a>
或
<a href="javascript:void(0);">Click me</a>