防止Backbone pushState上的整页重新加载

时间:2011-10-03 20:38:03

标签: backbone.js

我正在尝试使用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});

5 个答案:

答案 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>