【问题标题】:How do you do something when the escape key is pressed on an input field, but not on blur events for that input field?当在输入字段上按下转义键而不是在该输入字段的模糊事件上时,您如何做某事?
【发布时间】:2015-03-17 18:57:10
【问题描述】:

例如,考虑TodoMVC app

我正在编写我自己的那个应用程序版本。当您双击待办事项时,会显示一个输入字段。

当输入字段模糊时,我想保存更改。但是如果用户进行更改然后按escape,我不想保存更改。

问题是在输入字段上按下 escape 键会触发模糊事件。因此,当我按下转义键时,我拥有的监听 escape 按键的函数会运行......但监听模糊事件的函数也会运行。

escape键被按下时如何做一些事情,而不运行模糊事件功能?


views/todo.js

var app = app || {};

app.TodoView = Backbone.View.extend({
  tagName: 'li',

  className: 'list-group-item',

  template: _.template( $('#todo-template').html() ),

  render: function() {
    this.$el.html( this.template(this.model.toJSON()) );
    this.$el.find('.edit-mode').hide();
    this.$el.find('.remove-todo').hide();
    return this;
  },

  events: {
    'click input[type="checkbox"]': 'check',
    'mouseenter': 'showRemove',
    'mouseleave': 'hideRemove',
    'click .remove-todo': 'remove',
    'dblclick .todo-title': 'showEditMode',
    'keyup input.edit-todo': 'updateOnEnter',
    'blur input.edit-todo': 'closeAndUpdate'
  },

  initialize: function() {
    this.listenTo(this.model, 'change', this.render);
  },

  check: function(e) {
    this.model.save({
      completed: true
    });
  },

  showRemove: function(e) {
    $(e.currentTarget).find('.remove-todo').show();
  },

  hideRemove: function(e) {
    $(e.currentTarget).find('.remove-todo').hide();
  },

  remove: function(e) {
    var $el = $(e.currentTarget);
    this.model.destroy({
      success: function(model) {
        app.todos.remove(model);
        $el.closest('li').remove();
      },
      error: function() {
        alert('Unable to remove todo.');
      }
    });
  },

  showEditMode: function(e) {
    var $el = $(e.currentTarget);
    var $editMode = $el.closest('li').find('.edit-mode');
    $el.closest('.view-mode').hide();
    $editMode.show();
    $editMode.find('.edit-todo').focus();
  },

  updateOnEnter: function(e) {
    if (e.which === 13) {
      this.closeAndUpdate();
    }
    else if (e.which === 27) {
      this.closeEditMode();
    }
  },

  closeEditMode: function() {
    var $input = this.$el.find('.edit-todo');
    $input.closest('li').find('.view-mode').show();
    $input.closest('.edit-mode').hide();
  },

  closeAndUpdate: function() {
    var self = this;
    var $input = this.$el.find('.edit-todo');
    var newTitle = $input.val();
    if (newTitle !== this.model.get('title')) {
      this.model.save({
        title: newTitle
      }, {
        success: function(model) {
          self.closeEditMode();
        },
        error: function() {
          alert('Unable to update todo');
        }
      });
    }
    else {
      this.closeEditMode();
    }
  }
});

【问题讨论】:

  • @thomas 我刚刚意识到 - 默认情况下,逃逸不会触发模糊。只是我在按下转义时手动切换到“查看模式”,而 是触发模糊事件的原因。

标签: javascript jquery backbone.js backbone-events


【解决方案1】:

您可以在按下 Esc 时在 keypress 处理程序内设置一些布尔标志,然后在 blur 处理程序内检查它:

...
events: {
  ...
  "keypress .edit"  : "keypress",
  "blur .edit"      : "blur"
},
...
close: function() {
  ...
},
blur: function() {
  if (!this.escFlag) this.close();
  this.escFlag = false;
},
keypress: function(e) {
  if (e.keyCode == 27) this.escFlag = true;
},
...

【讨论】:

  • 你怎么知道updateOnEnter是否总是在blur之前运行?
  • @Adam Zerner 来自the docs 的引用:如果注册了多个处理程序,它们将始终按照它们绑定的顺序执行。所以你只需要确保keypress处理程序是在blur之前定义的
  • 好的。好吧,您的方法有效,而且看起来很合理。不过,在选择最佳答案之前,我想先听听其他想法。
  • @hindmost 该文档摘录涉及单个事件(例如,当您在 blur 事件上注册多个处理程序时。不同事件的处理程序将按照事件被调度的顺序触发。我不不知道keypressblur之间的顺序是否指定,但是最近在blur之前拦截keydown没有成功,所以浏览器之间可能会有所不同。
猜你喜欢
  • 2015-01-29
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-24
相关资源
最近更新 更多