检测 HTML 文本字段中发生的更改
对于一个主要的学校项目,我正在实施一个实时协作编辑器。简单介绍一下背景知识,这基本上意味着两个(或更多)用户可以同时在文档中键入内容,并且他们的更改会自动传播到彼此(类似于 Etherpad)。
现在我的问题如下:
我希望能够检测用户对 HTML 文本字段进行了哪些更改。他们可以:
- 插入一个字符
- 删除一个字符
- 粘贴一串字符
- 剪切一串字符
我希望能够检测到发生了哪些更改,然后通知其他客户端,类似于“在位置 2 插入字符‘c’”等。
不管怎样,我希望得到一些关于如何实施这些变化检测的建议?
我的第一次尝试是考虑发生变化之前和之后的胡萝卜位置,但这惨败了。
对于我的第二次尝试,我正在考虑对文本字段旧值和新值的全部内容进行比较。我是否遗漏了这个解决方案的任何明显内容?有没有更简单的东西?
For a major school project I am implementing a real-time collaborative editor. For a little background, basically what this means is that two(or more) users can type into a document at the same time, and their changes are automatically propagated to one another (similar to Etherpad).
Now my problem is as follows:
I want to be able to detect what changes a user carried out onto an HTML textfield. They could:
- Insert a character
- Delete a character
- Paste a string of characters
- Cut a string of characters
I want to be able to detect which of these changes happened and then notify other clients similar to "insert character 'c' at position 2" etc.
Anyway I was hoping to get some advice on how I would go about implementing the detection of these changes?
My first attempt was to consider the carot position before and after a change occurred, but this failed miserably.
For my second attempt I was thinking about doing a diff on the entire contents of the textfields old and new value. Am I missing anything obvious with this solution? Is there something simpler?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于多种原因,今天要使其正常工作确实是一项艰巨的工作,但
也许您只需要限制某些浏览器。阅读:https://developer.mozilla.org/en/XUL/Attribute/oninput“oninput”的替代方案是监听所有输入事件(键盘、鼠标、拖放)我建议使用“oninput”
html 并不完美......即使是 html5。输入和文本区域仅支持单范围
选择。你可以使用 designmode/contenteditable 来解决这个问题,而不是
textareas/textfield
检测更改的偏移量是一项艰巨的工作:阅读
-- https://developer.mozilla.org/en/Document_Object_Model_%28DOM %29/window.getSelection
-- http://www.quirksmode.org/dom/range_intro.html -- http://msdn.microsoft.com/en -us/library/ms535869%28v=VS.85%29.aspx -- http://msdn.microsoft.com/en-us/library/ms535872%28v=VS.85%29.aspx
您可能需要一个“ diff”用javascript编写的算法! http://ejohn.org/projects/javascript-diff-algorithm/
一个个人注意:检测单词、字符的变化可能完全没有意义,也没有用,而是检测段落变化,或者在类似 excel 的工作表中,单个单元格,
我希望这有助于
随意纠正我的英语!
It is a really hard work make this working today, for several reasons, but
maybe you will need to restrict only to some browsers. read: https://developer.mozilla.org/en/XUL/Attribute/oninput the alternative to "oninput" is listen to all input events (keyboard, mouse, dragdrop) I suggest to use "oninput"
html is not perfect... even html5. input and textareas supports only single-range
selections. you can solve this using designmode/contenteditable instead of
textareas/textfield
detecting offsets of what changed is a hard work: read
-- https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/window.getSelection
-- http://www.quirksmode.org/dom/range_intro.html -- http://msdn.microsoft.com/en-us/library/ms535869%28v=VS.85%29.aspx -- http://msdn.microsoft.com/en-us/library/ms535872%28v=VS.85%29.aspx
you may need a "diff" algorithm written in javascript! http://ejohn.org/projects/javascript-diff-algorithm/
one personal note: detecting words, characters changes may be totally non-sense and not useful, detect instead paragraphs changes, or in case of an excel-like worksheet, the single cell
I hope this helps
feel free to correct my English!
我的伪代码/写出的响应将是(如果我完全理解你的问题)使用 jQuery 来检测 keyup 事件,然后通过 ajax 将输入保存到服务器,然后还获取响应并将其发布回输入。这不是很有效,但基本上的想法是您不断发布并检查其他已发布的内容。如果您想实时查看其他人在做什么,您可以每隔一秒左右对服务器执行一次 ping 操作,并使用响应进行更新。
所有这些当然都可以优化,但对服务器来说仍然是一种负担。您还可以看看是否可以为您的项目实施
GoogleTopeka Wave,或者与GoogleTopeka 联系,看看他们是如何做到的:)My pseudocode/written out response would be (if I understand your question exactly) to use jQuery to detect keyup events and then save the input to the server via ajax, then also take the response and post it back to the input. This isn't very efficient, but basically the idea is that you're constantly posting and checking what else has been posted. If you want to see what someone else is doing in real time, you can ping the server every second or so and update with the response.
All of this of course can be optimized, but it still is kind of taxing for a server. You could also see if you can implement
GoogleTopeka Wave for your project, or get in touch withGoogleTopeka to see how they do it :)