保存键控触发器时保持光标位置的最佳做法

Best practice to maintain cursor position when keyup triggers save

本文关键字:位置 最佳 光标 触发器 保存      更新时间:2023-09-26

我正在使用Backbone.js。在我看来,我有一个textarea,其keyup绑定到这样的函数(但请参阅下面的编辑):

this.model.save({text: self.$('textarea').val()}, {patch: true});

在视图的initialize函数中,我将模型的change事件绑定到视图的render函数:

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

问题是,当用户键入textarea时,会发生以下事件序列:

  1. keyup事件将触发。
  2. keyup处理程序调用模型上的save
  3. save的调用会触发模型的change事件。
  4. 侦听模型change事件的视图调用render
  5. textarea在 DOM 中被替换。
  6. textarea不再聚焦,并且文本光标位置丢失。

在这种情况下,texareakeyup事件需要触发同步,最佳做法是什么?我考虑过的一些选项:

  1. 不要将change绑定到render。缺点:如果模型数据由于用户键入以外的任何内容而更改,则文本区域不会自动更新。
  2. 阅读并记住render开头的光标位置。在render 的末尾设置光标位置。缺点:取决于浏览器支持参差不齐的光标操作功能。
  3. keyup处理程序中,在视图上设置一个临时属性,告知它不要重新呈现。保存模型后取消设置。缺点:感觉像意大利面条代码,与Backbone的结构作斗争。

有什么我没有看到的选项吗?您是否推荐上述选项之一?

编辑

我不想分散主要观点的注意力,但是由于它出现在其中一个答案中:我不直接绑定keyup,而是用_.debounce中介它。因此,事件处理程序仅在用户停止键入后运行,由自上次keyup以来经过的一定时间量定义。

首先,

我想阻止这样做,因为在keyup上保存您的模型似乎是一种非常奇怪的行为。如果有一个用例确实需要这样做,我建议至少使用 input 事件 - 否则每次用户按下箭头键、shift、ctrl 等时,您最终都会保存模型。

我认为您还希望将输入事件反弹 500 毫秒左右,因此您实际上并没有在每次击键时都保存模型。

要解决您在第 1 点中的评论:

缺点:如果模型数据由于 用户键入时,文本区域不会自动更新

您需要问问自己发生这种情况的可能性,以及如果发生这种情况,重新呈现视图的重要性。

最后,如果您确定这确实是可能的,并且重新呈现视图很重要,那么您可以尝试这样的事情

http://jsfiddle.net/nuewwdmr/2/

此处的重要部分之一是将模型属性名称映射到输入的名称字段。我在这里所做的遵循您上面描述的事件顺序。不同之处在于,当模型更改时,我们检查更改的属性并更新模板中相应元素的值。

这在非常简单的情况下工作正常,即快乐路径,其中用户以"正常"方式输入输入。但是,如果用户决定返回到输入的开头并更改一个字母以将其大写,例如,在模型中发生更改事件后,光标将跳到字符串的末尾。

您在这里需要的行为实际上是双向数据绑定,这绝不是微不足道的,尤其是对于 Backbone,因为 Backbone 视图的功能很少。

我的建议将是你的观点 1

不将更改绑定到呈现

编辑

如果您想进一步了解模型/视图绑定,可以查看两个库:

粘性

环氧的

我以前用过粘性,它是...好。不太好。对于简单的绑定是可以的,例如将"顶级"模型属性绑定到输入元素。一旦你进入嵌套属性,你就会遇到问题,然后你将不得不研究像Backbone Deep Model这样的东西。

就像我说的,Backbone's View并没有提供太多。如果你有时间,我建议你考虑使用 React 组件来代替 Backbone Views,或者甚至看看 & 符号必须提供的一些有趣的东西。