В одностраничных приложениях (SPA) управление фокусом является критически важным аспектом для обеспечения доступности и удобства взаимодействия пользователя с интерфейсом. Backbone.js предоставляет структурированные инструменты для организации кода, и правильная интеграция управления фокусом с его компонентами позволяет создавать более предсказуемые и отзывчивые интерфейсы.
Фокус в DOM определяется элементом, который в данный момент готов принимать пользовательский ввод. В SPA фокус может теряться при динамическом изменении контента, что особенно критично для:
Ключевые задачи управления фокусом:
Backbone.js строит интерфейс вокруг View, которые управляют отображением и событиями элементов DOM. Управление фокусом интегрируется через:
Пример базовой структуры:
var FormView = Backbone.View.extend({
tagName: 'form',
events: {
'keydown input': 'handleKeyDown'
},
render: function() {
this.$el.html('<input type="text" class="name"/><input type="text" class="email"/>');
this.setInitialFocus();
return this;
},
setInitialFocus: function() {
this.$('.name').focus();
},
handleKeyDown: function(e) {
if (e.key === 'Enter') {
this.focusNextField(e.target);
}
},
focusNextField: function(current) {
var fields = this.$('input');
var index = fields.index(current);
if (index + 1 < fields.length) {
fields.eq(index + 1).focus();
}
}
});
В этом примере:
SPA часто динамически подгружает и заменяет контент, поэтому необходимо отслеживать моменты, когда элементы появляются в DOM:
render: function() {
this.$el.html(this.template());
this.afterRender();
return this;
},
afterRender: function() {
var firstInput = this.$('input').first();
if (firstInput.length) {
firstInput.focus();
}
}
var ListView = Backbone.View.extend({
initialize: function() {
this.listenTo(this.collection, 'add remove reset', this.render);
},
render: function() {
this.$el.empty();
this.collection.each(function(model) {
this.$el.append('<div tabindex="0">' + model.get('name') + '</div>');
}, this);
this.setFocusOnFirstItem();
return this;
},
setFocusOnFirstItem: function() {
this.$('div').first().focus();
}
});
Здесь после каждой модификации коллекции фокус автоматически перемещается на первый элемент списка.
Модальные окна требуют строгого контроля фокуса, чтобы пользователь не терял ориентацию:
Пример:
var ModalView = Backbone.View.extend({
events: {
'keydown': 'trapFocus'
},
open: function(triggerElement) {
this.$el.show();
this.triggerElement = triggerElement;
this.$el.find('[tabindex]').first().focus();
},
trapFocus: function(e) {
var focusable = this.$el.find('[tabindex]');
var first = focusable.first()[0];
var last = focusable.last()[0];
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
},
close: function() {
this.$el.hide();
if (this.triggerElement) {
this.triggerElement.focus();
}
}
});
Особенности реализации:
Для полной доступности SPA необходимо учитывать:
aria-modal,
aria-labelledby, aria-hidden.Backbone.js позволяет встроить эти практики через методы View и события модели, обеспечивая реактивное обновление интерфейса и предсказуемое управление фокусом.
Эффективное управление фокусом в Backbone.js повышает удобство использования SPA и обеспечивает соответствие современным стандартам доступности.