【问题标题】:Keyboard TAB navigating broken when using backbone.js使用backbone.js时键盘TAB导航损坏
【发布时间】:2025-11-23 14:50:01
【问题描述】:

TAB 导航中断,因为渲染替换了 DOM 元素。

主干渲染方法旨在处理整个视图的标记,而不仅仅是更改内容...

鉴于以下情况 - 我在 html 标签上正确设置了 tabindex 以指定 tab 顺序。 - 我使用键盘上的 TAB 从一个字段导航到另一个字段。 - 当模型状态改变时,我绑定到调用渲染的更改更改事件:- this.model.bind('改变', this.render); - 我将某个字段和选项卡中的某些内容更改为下一个(这会触发模型更改事件)

有没有人在没有显式代码检查所有更改的属性的情况下解决这个问题,也没有替换骨干网(因为这不是当前项目的选项)

例子:

启动TODO 应用程序创建 2 个 TODO,Ta​​b 到第一个 TODO,然后按空格标记为已完成。然后尝试切换到下一个字段,而不是转到下一个 TODO,而是回到需要完成的输入:(

【问题讨论】:

  • 问题是复选框更新后失去焦点;您只需要重新聚焦已更改的项目。
  • 不要在更改事件上致电render。创建一个不完全替换 HTML 的新函数(更新?)
  • @CoryDanielson 但是我必须自己操作 DOM,这是主干试图解决的问题......
  • 好吧,我认为您可以在模型上观察change 事件,提取 ID,然后从中集中注意力。我认为您不需要额外的数据; lastFocused 可以从现有数据中推导出来,不是吗?如果您发布一些您当前的代码,我很乐意提供一个示例。
  • Backbone 的目的不是简化 DOM 交互。它更像是一个代码组织/流库。如果您不想接触 DOM,Ember 可能对您来说是正确的。不过有很多方法可以解决这个问题。您可以存储一个值以了解您关注的 TODO,重新渲染“完成”的 TODO,然后使用存储的值重新关注它。您应该创建一个模板,其中包含 TODO 的文本框以及隐藏在屏幕外的完成模板。当你将它标记为完成时,你只是在同一个 TODO 项目上切换一个类。 TODO 周围的表单标签也可能很有用。

标签: javascript backbone.js


【解决方案1】:

这是我最终得到的解决方案:-

它为所有没有id的元素添加一个生成的id,这些id对于相同状态的模型来说是相同的。

render: function(x) {
  var html = this.options.template(this.model.toJSON());
  var focused = window.document.activeElement.id; //Get the focused element
  this.el.innerHTML = html;
  this.decorate();
  if (focused) $('#' + focused).focus(); //Focus if previously focused prior to innerHTML
  return this;
},

decorate: function() {
  var i = 0;
  var idPrefix = 'ENTER PREFIX HERE'
  this.$el.find('*').each(function() {
    if (!this.id) this.id = idPrefix + ((++i).toString(36)); //Add id if none exists
  });
}

【讨论】: