如何有效地记录用户打字使用javascript
How to efficiently record user typing using javascript?
我希望能够记录然后播放在文本区发生的任何事情。
我遇到过一些解决方案,但他们不可靠,像通过AJAX发送每个击键。在这种情况下,我最终会有数百万行在我的数据库。
我想到的想法是将击键记录到客户端的一个变量中,用动作更新该变量,但要跟踪每次击键之间的时间。还要确保它也支持删除数据。
最后,我将整个变量发送到db一次,然后我可以解码它以后播放。
这个变量应该是什么样子的思维导图:
hellooo[1.2][backspace][0.6][backspace]World![return]
Idle time __^ Removes one char __^
我相信google docs正在做类似的事情来回放用户输入的内容。
任何想法?
幸运的是JavaScript事件已经为您处理了所有编码问题。你可以直接把keyup/keydown/keypress/诸如此类的整个事件对象扔到一个数组中。
每个对象包含:
- 事件类型时间戳
- 使用了哪个键(或多个键的组合)
- 什么是焦点
- 其他一些可能最终有用的东西。
你可以对数组进行编码,然后用你最喜欢的ajax方法将其发送到服务器进行存储。
所以你的代码只需要一个可以存储数据的函数。不要使用这个函数,它只是为了演示。
var handler = function (e) {
handler.data.push(e);
console.log(handler.data);
}
handler.data = [];
window.addEventListener("keyup", handler);
window.addEventListener("keydown", handler);
window.addEventListener("keypress", handler);
因为它是一个数组,它们应该都是有序的,但是在奇怪的事件中,它出错了,你有每个事件的时间戳数据(这也让你发现事件之间的延迟,这是AWESOME如果你有混合按键。)。
然后你可以按照你想要的方式来重放事件——但是现在你不需要发明你自己的规范,因为w3c的可爱的家伙在设计DOM事件规范时已经为你做了所有的艰苦工作。
存储每个操作的时间和该操作的结果,并在完成时序列化日志并存储。
单独重放每个动作太复杂了。假设用户向后移动了几个字符,并在那里添加了新的字符。您需要跟踪光标的位置。
只需记住每次击键时文本区域的整个值。没有必要记住是怎么发生的,对吧?
这是一个实现。小提琴
<textarea id="recorder"></textarea>
<textarea id="playback"></textarea>
<script type="text/javascript">
var Playback = {
//store the time an action occured and the resulting state in an object
//don't use an array because they are not sparce - interstitial keys
//will have to be iterated over
record: {},
init: function( recorderId, playbackId ) {
this.recorder = document.getElementById( recorderId );
this.playback = document.getElementById( playbackId );
this.recorder.addEventListener( 'focus', function() {
Playback.record = {};
this.value = '';
}, false );
this.recorder.addEventListener( 'keyup', function( e ) {
Playback.record[ (new Date()).getTime() ] = this.value;
}, false );
this.recorder.addEventListener( 'blur', function( e ) {
Playback.playback.value = '';
//store the time the sequence started
//so that we can subtract it from subsequent actions
var mark = null;
for( var t in Playback.record ) {
if( mark ) {
var timeout = t - mark;
} else {
var timeout = 0;
mark = t;
}
// We need to create a callback which closes over the value of t
// because t would have changed by the time this is run
setTimeout( Playback.changeValueCallback( Playback.record[t] ), timeout );
}
}, false );
},
changeValueCallback: function( val ) {
return function() { Playback.playback.value = val }
}
}
Playback.init( 'recorder', 'playback' );
</script>
注意:事件处理仅适用于兼容的浏览器,您需要自己适应internet explorer
数据库是用来处理数百万条记录的,所以这不是真正的问题。
如果您仍然不想这样做,您可以将与会话相关的所有数据编码为JSON,并将其存储在数据库中的文本字段中或作为服务器上的文件。在这种情况下,如果数据非常大,则可能需要一段时间才能加载数据并将其发送到浏览器,从而导致用户延迟。
- 从 DOM 中删除/删除 Javascript 用户定义的数组
- Ajax/Javascript用户状态更新
- javascript用户输入最多的20个数字
- Javascript 用户 ID 代码
- PHP/JavaScript 用户信息收集
- hta文件中的javascript用户配置文件相对路径
- 使用Javascript用户输入修改CSS
- 如何将Javascript用户的用户数据返回到Django
- 跨域javascript用户验证
- JavaScript用户脚本本身不运行
- HTML Imagemap与PHP和Javascript /用户可以选择颜色
- 为非JavaScript用户嵌入Youtube视频
- JavaScript用户输入URL不持有我的域
- 表单动作改变javascript用户选项选择
- Asp.net: c#/javascript用户在提交之前需要确认
- 非javascript用户的非javascript弹出窗口
- JavaScript -用户的安全覆盖变量
- 我如何保护我的PHP cookie从JavaScript用户的页面
- Javascript用户代理按浏览器版本号重定向
- Javascript用户的输入验证