javascript - 第一次单击时会跳过主干 View 中的 Jquery 事件

标签 javascript jquery backbone.js

我有一个切换事件,用于显示和隐藏 div,它连接在主干 View 内并通过事件委托(delegate)调用。第一次点击链接时,toggle() 会被跳过。在第二次和第三次单击时,toggle() 会按预期调用。

有什么想法可以让切换事件在第一次点击时工作吗?

events:{
    "click a.docSectionHeading" : "Expand" 
  },

  initialize: function(options) {
    _.bindAll(this, "render", **"Expand"**);
    this.model.bind("change", this.render);      
    this.model.fetch();
  },

  render: function() {    
    var $el = $(this.el);
    $el.empty();
    $el.append(this.template.to_html({
      message: this.model.get("message")  
    }));

    return this;
  },

  Expand: function() {

    var tempid = "";
    var id = "";

    // Not called on first click
    $("a.docSectionHeading").toggle(
      function () {

        tempid = $(this).attr("data-id");
        id = tempid.replace(".", "\\.");

         // show -, hide +
        $("img#doc_minus_" + id).removeClass(".noShow");
        $("img#doc_minus_" + id).show();
        $("img#doc_plus_" + id).hide();

        // show clicked section.
        $("#" + id).show();
      },

      function(){
        tempid = $(this).attr("data-id");
        id = tempid.replace(".", "\\.");

         // show -, hide +
        $("img#doc_minus_" + id).addClass(".noShow");
        $("img#doc_minus_" + id).hide();
        $("img#doc_plus_" + id).show();

        // show clicked section.
        $("#" + id).hide();
      }
    )

    return false;
  }

最佳答案

jQuery 切换绑定(bind)了单击切换行为,因此第一次单击它时,用于处理切换的事件会被绑定(bind),但不会被触发,因为它尚未绑定(bind)并且没有任何反应,这就是它在第二次单击时起作用的原因。这里的另一个问题是,现在每次单击都会一次又一次地绑定(bind)事件,这将使事件随着时间的推移多次触发,并且可能会产生各种不同类型的难以跟踪的错误+性能会受到影响。

要解决这个问题,您需要在渲染模板后在渲染方法中绑定(bind)切换事件,或者创建一个辅助方法 bindToggle 或类似的方法,然后在渲染方法中调用它已经渲染了模板。

编辑:和一些提示

  • 这是一个被广泛接受的标准,方法名称以小写开头,类/构造函数名称以大写开头 - 这可能会让其他程序员感到困惑。
  • 你使用empty然后追加 - 它相当于jquery html它将清空然后追加你的html/DOM节点
  • 如果您将事件绑定(bind)到元素,则无需再次查询它,您可以使用 $(event.target) 从事件对象中获取它
  • 如果您使用的是 Backbone 0.9+,则不需要使用 $(this.el) 来获取表示元素的 jquery 对象,您只需通过访问即可使用 jquery 包装元素的缓存副本this.$el
  • 此外,如果您要查询的元素是当前 View 元素的子元素,那么使用主干 this.$ 方法会更有效(this.$('a.docSectionHeading ')),因为它的效率要高得多,因为这只会在当前元素的子元素中搜索该元素。它还允许您查询尚未添加到文档 DOM 树中的元素。

ps。并希望bindAll中的**“Expand”**只是一个错误?星星有什么用?

固定代码:

initialize: function(options) {
  _.bindAll(this, "render");
  this.model.bind("change", this.render);      
  this.model.fetch();
},

render: function() {    
  var $el = $(this.el);
  $el.empty();
  $el.append(this.template.to_html({
    message: this.model.get("message")  
  }));

  this.bindExpand();

  return this;
},

bindExpand: function() {

  var tempid = "",
      id = "";

  this.$("a.docSectionHeading").toggle(
    function () {

      tempid = $(this).attr("data-id");
      id = tempid.replace(".", "\\.");

       // show -, hide +
      $("img#doc_minus_" + id).removeClass(".noShow");
      $("img#doc_minus_" + id).show();
      $("img#doc_plus_" + id).hide();

      // show clicked section.
      $("#" + id).show();
    },

    function(){
      tempid = $(this).attr("data-id");
      id = tempid.replace(".", "\\.");

       // show -, hide +
      $("img#doc_minus_" + id).addClass(".noShow");
      $("img#doc_minus_" + id).hide();
      $("img#doc_plus_" + id).show();

      // show clicked section.
      $("#" + id).hide();
    }
  );
}

关于javascript - 第一次单击时会跳过主干 View 中的 Jquery 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9337318/

相关文章:

javascript - 在 script.aculo.us 中使用 jQuery noConflict()

javascript - jquery 移动圆形导航后退按钮

jquery - 用 JQuery 覆盖正文背景?

javascript - IntroJS 条件步骤

javascript - 无法正确显示号码

javascript - 通过 JSONP 的 sencha touch 动态列表

javascript - 我对 Ember.View 的解释感到困惑

javascript - Backbone - 如何重构此代码以防止重影 View ?

collections - 主干_.each collection.model为空

javascript - Backbone : Show validation errors for each model in a collection on VIEW