For example, consider the TodoMVC app.
I'm writing my own version of that app. When you double click a todo item, an input field shows up.
When that input field blurs, I want to save the changes. But if the user makes changes and then presses escape, I don't want to save the changes.
The problem is that pressing the escape key on the input field triggers a blur event. So when I press escape, the function I have that listens for escape key presses runs... but so does the function that listens for the blur event.
How can I do something when the escape key is pressed, and not run the blur event function?
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({
pleted: 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();
}
}
});
For example, consider the TodoMVC app.
I'm writing my own version of that app. When you double click a todo item, an input field shows up.
When that input field blurs, I want to save the changes. But if the user makes changes and then presses escape, I don't want to save the changes.
The problem is that pressing the escape key on the input field triggers a blur event. So when I press escape, the function I have that listens for escape key presses runs... but so does the function that listens for the blur event.
How can I do something when the escape key is pressed, and not run the blur event function?
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({
pleted: 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();
}
}
});
Share
Improve this question
edited Apr 2, 2022 at 13:19
Brian Tompsett - 汤莱恩
5,89372 gold badges61 silver badges133 bronze badges
asked Mar 17, 2015 at 18:57
Adam ZernerAdam Zerner
19.4k18 gold badges101 silver badges175 bronze badges
1
- @thomas I just realized - escape doesn't trigger blur by default. It's just that I manually switch to 'view-mode' when escape is pressed, and that is what triggers the blur event. – Adam Zerner Commented Mar 17, 2015 at 19:27
1 Answer
Reset to default 5You can set some boolean flag inside keypress
handler when Esc is pressed, and then check it inside blur
handler:
...
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;
},
...
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745453045a4628359.html
评论列表(0条)