|
| 1 | +document.addEventListener('DOMContentLoaded', () => { |
| 2 | + const textToType = "p'uco wnqum i/min crj'i gt;pl pwvd. pxlxm 'smdq g[cgo ivat; jh[ud vdizb bskts nnotb dw';, u,ko. ocm/z hld.p h/cur cenvd vj/sn h/,y. gz;an mlrgm dt,.n wajf/ /r'xi /h'pp qiwvt hcb/u 'gcg[ 'yqra khbdq tfdf; sojp, zm[wj ;sj[y pczzo ktji; iegid xjkk/ ;vm.i l''n/ h'cyx sk.'f iutza 'ydf, gtqga fvuie gyqy. v[h,; ebj[/ mkzwt icw[x txliv px.c[ wurbg ./krh o.hli a;cqv nntp; rix[. wrxhq 'lmni hwhza urg[' fs[v/ qeldu eol'f ugqgu y'hbk wuqr; gd'xf c,'im l.;hs [qyt' c/yhf w'lj/ tttbg '[qp. vkvb/ .qspv .nfg' mohw. t[ntx c.qlf /o'qb b;ygs defu. y;gnv ghiz' yly.. z;mm[ cgj/w qkei, xo;uf qqjmk zqp;k cgko; .dkbn rpihv pb;[s wbiem u,lsz vabzy ,obqm tmtoj p/;[u rz;[o c/k,[ ;/;vy qsxmr c.xrd ybtm[ e'[/h amfq/ [yxnc z'prc mox'a thvnn gofxr e.tfm i.pyb xrauq kv,vs nnyed sd[hs miwfp cknsf jvxxm qeba, dquls myprm ;'qpc ;;c,. .a.[p r/qvc jo'mg ahhet ,jk'u wo.c. qtzlr ;'i., hjp/n ztpkc j;qxw l;vl, tc;lr ;qwx. utq,' rlack ddcwu i;u/j jaskd ixeye r;[s' bhpdv pulbw qcyp/ pahls yirfi xl[oz ss;xx ,gt'u ,avqm pemkd rpdk"; // Replace with your text |
| 3 | + const container = document.getElementById('text-container'); |
| 4 | + container.innerHTML = textToType.split('').map(char => `<span>${char}</span>`).join(''); |
| 5 | + |
| 6 | + let currentIndex = 0; |
| 7 | + const keystrokeData = []; |
| 8 | + |
| 9 | + document.addEventListener('keydown', (e) => { |
| 10 | + e.preventDefault(); // Prevent default browser actions |
| 11 | + if (['Backspace', 'Tab', 'ArrowLeft', 'ArrowRight', 'Enter'].includes(e.key)) { |
| 12 | + return; // Still prevent the use of these keys |
| 13 | + } |
| 14 | + |
| 15 | + const keyPressTime = new Date().getTime(); |
| 16 | + const currentChar = textToType[currentIndex]; |
| 17 | + const span = container.getElementsByTagName('span')[currentIndex]; |
| 18 | + const isCorrect = e.key === currentChar; |
| 19 | + |
| 20 | + span.className = isCorrect ? 'correct' : 'incorrect'; |
| 21 | + |
| 22 | + keystrokeData.push({ |
| 23 | + expected: currentChar, |
| 24 | + typed: e.key, |
| 25 | + match: isCorrect ? 1 : 0, |
| 26 | + pressTime: keyPressTime, |
| 27 | + releaseTime: null // This will be filled on keyup |
| 28 | + }); |
| 29 | + |
| 30 | + currentIndex++; |
| 31 | + updateTable(); |
| 32 | + }); |
| 33 | + |
| 34 | + document.addEventListener('keyup', (e) => { |
| 35 | + const keyReleaseTime = new Date().getTime(); |
| 36 | + if (keystrokeData[currentIndex - 1]) { |
| 37 | + keystrokeData[currentIndex - 1].releaseTime = keyReleaseTime; |
| 38 | + updateTable(); |
| 39 | + } |
| 40 | + }); |
| 41 | + |
| 42 | + function updateTable() { |
| 43 | + const tbody = document.getElementById('keystroke-data').getElementsByTagName('tbody')[0]; |
| 44 | + tbody.innerHTML = ''; |
| 45 | + keystrokeData.forEach(data => { |
| 46 | + const row = tbody.insertRow(); |
| 47 | + Object.values(data).forEach(text => { |
| 48 | + const cell = row.insertCell(); |
| 49 | + cell.appendChild(document.createTextNode(text)); |
| 50 | + }); |
| 51 | + }); |
| 52 | + } |
| 53 | +}); |
0 commit comments