5

我的 html 文件中有这个:

<textarea id="inputbox" placeholder="type here"></textarea>

连接一个处理程序的正确方法是什么,该处理程序会在文本区域的内容发生变化时立即触发?(无论是通过键盘、鼠标/剪贴板、语音输入、脑波阅读器等)

我试过了:

  query("#inputbox").on.change.add(handler)

但是(至少在 Dartium 上)它只会在您离开现场后触发。

目的是更新“实时预览”窗口,类似于 Stackoverflow 在您键入时呈现 Markdown 输出的方式。

4

2 回答 2

9

这是迄今为止我想出的最好的。如果有人知道更紧凑或更优选的替代方案,我将很高兴听到。

编辑:代码片段更新为事件注册的新模式。

import 'dart:html';

void main() {
  query("#inputbox")
    ..onChange.listen(handler)
    ..onKeyDown.listen(handler)
    ..onKeyUp.listen(handler)
    ..onCut.listen(handler)
    ..onPaste.listen(handler);
}

void handler(Event event) {
  print((query("#inputbox") as TextAreaElement).value);
}

浏览器和操作系统之间的精确行为会有所不同。

您可以跳过keyDown,但要注意keyDownkeyUp行为受操作系统影响,并且不能保证是对称的。您可能会错过更改,至少在下一个keyUp更改事件被触发之前。事实上,我通过在 Windows 7 上创建一个小应用程序来向 Dartium 和 IE9 发送孤立的 WM_KEYDOWN 消息证明了这一点。

keyPress可以用来代替keyUpkeyDown,但不会为某些键(如退格键和删除键)生成事件。

cutpaste立即对使用鼠标执行的剪切或粘贴做出反应。如果您不使用它们,该change事件将捕获更改,但直到字段失去焦点之后,或者有时甚至更晚

input事件可以替换上面的所有侦听器,并且在 Dartium 中似乎工作得很好,但在 IE9 下它只捕获字符添加,而不是删除。

注意keyUpkeyDown可能为光标键、home、end、shift 等生成额外的不需要的事件(例如在 IE9 中)。当用户使用快捷键进行这些操作时,除了剪切/粘贴侦听器之外,它还会触发。

虽然这个问题是针对 Dart 的,但上面的很多讨论都适用于任何监听 DOM 的代码。甚至keyCode也没有跨浏览器标准化(更多细节)。

检查一下KeyboardEventController类也可能是值得的,但总的来说,当我测试它时,边缘情况的行为与上面提到的类似。这可能是也可能不是设计使然。Dart 开发人员确实做出了一些努力来使您免受跨浏览器不一致的影响,但它仍在进行中。

另外,当我们谈论textarea时,请记住使用它的value属性,而不是它的text属性。最后,请确保您handler限制它对“突发”键盘活动的反应(例如,某种计时器会暂时延迟处理程序的内部并汇总同时发生的任何其他事件)。

相关问题和链接:

于 2013-01-21T06:08:18.207 回答
2

目前尚不清楚您是否使用聚合物,但如果您使用了,您可以通过在聚合物元素中以 [变量名称]Changed(oldvalue) 的形式在聚合物元素中创建一个函数来订阅对使用 @observable 注释的变量的更改。我最初在这里找到了这个:如何订阅可观察字段的更改

于 2013-12-09T02:32:13.023 回答