@@ -27,7 +27,8 @@ function getTypingSpeedTesterHTML() {
2727
2828 <button
2929 id="startTypingBtn"
30- class="btn-play"
30+ type="button"
31+ class="btn-generate"
3132 style="
3233 margin-bottom: 20px;
3334 font-weight: 700;
@@ -45,7 +46,8 @@ function getTypingSpeedTesterHTML() {
4546
4647 <button
4748 id="newSentenceBtn"
48- class="btn-play"
49+ type="button"
50+ class="btn-generate"
4951 style="
5052 margin-bottom: 20px;
5153 margin-left: 10px;
@@ -120,11 +122,21 @@ function initTypingSpeedTester() {
120122 const result =
121123 document . getElementById ( "typingResult" ) ;
122124
125+ if (
126+ ! sentenceElement ||
127+ ! inputElement ||
128+ ! button ||
129+ ! newSentenceBtn ||
130+ ! result
131+ ) {
132+ return ;
133+ }
134+
123135 let startTime = null ;
124136 let currentSentence = "" ;
125137
126- // Disable typing initially
127138 inputElement . disabled = true ;
139+ inputElement . setAttribute ( "aria-disabled" , "true" ) ;
128140
129141 function generateSentence ( ) {
130142
@@ -138,21 +150,19 @@ function initTypingSpeedTester() {
138150 sentenceElement . innerHTML =
139151 currentSentence
140152 . split ( "" )
141- . map ( char =>
142- ` <span>${ char } </span>`
143- )
153+ . map ( function ( char ) {
154+ return " <span>" + char + " </span>" ;
155+ } )
144156 . join ( "" ) ;
145157
146158 inputElement . value = "" ;
147-
148159 inputElement . disabled = false ;
149-
160+ inputElement . removeAttribute ( "aria-disabled" ) ;
150161 inputElement . focus ( ) ;
151162
152163 result . innerHTML = "" ;
153-
154- startTime = new Date ( ) . getTime ( ) ;
155- }
164+ startTime = Date . now ( ) ;
165+ }
156166
157167 // Start Test
158168 button . onclick = function ( ) {
@@ -165,21 +175,12 @@ function initTypingSpeedTester() {
165175 generateSentence ( ) ;
166176 } ;
167177
168- // Typing Event
169178 inputElement . addEventListener ( "input" , function ( ) {
170179
171- if ( ! startTime ) return ;
172-
173- const typedText =
174- inputElement . value ;
175-
176- // Current time
177- const currentTime =
178- new Date ( ) . getTime ( ) ;
180+ if ( ! startTime || ! currentSentence ) return ;
179181
180- // Total time in seconds
181- const totalTime =
182- ( currentTime - startTime ) / 1000 ;
182+ const typedText = inputElement . value ;
183+ const totalTime = Math . max ( ( Date . now ( ) - startTime ) / 1000 , 0.001 ) ;
183184
184185 // Correct characters
185186 let correctChars = 0 ;
@@ -190,6 +191,10 @@ function initTypingSpeedTester() {
190191
191192 const spans = sentenceElement . querySelectorAll ( "span" ) ;
192193
194+ for ( let i = 0 ; i < spans . length ; i ++ ) {
195+ spans [ i ] . style . color = "" ;
196+ }
197+
193198 for ( let i = 0 ; i < typedText . length ; i ++ ) {
194199
195200 if (
@@ -199,19 +204,20 @@ function initTypingSpeedTester() {
199204
200205 correctChars ++ ;
201206
202- spans [ i ] . style . color = "#22c55e" ;
207+ if ( spans [ i ] ) spans [ i ] . style . color = "#22c55e" ;
203208
204209 } else {
205210 incorrectChars ++ ;
206- spans [ i ] . style . color = "#ef4444" ;
211+ if ( spans [ i ] ) spans [ i ] . style . color = "#ef4444" ;
207212 }
208213 }
209-
210- // Accuracy
214+
211215 const accuracy =
212- Math . round (
213- ( correctChars / currentSentence . length ) * 100
214- ) ;
216+ currentSentence . length
217+ ? Math . round (
218+ ( correctChars / currentSentence . length ) * 100
219+ )
220+ : 0 ;
215221
216222 const mistakes = incorrectChars ;
217223
@@ -262,13 +268,9 @@ function initTypingSpeedTester() {
262268
263269 ` ;
264270
265- // LOCK TEST
266271 inputElement . disabled = true ;
267-
268- // REMOVE CURSOR
272+ inputElement . setAttribute ( "aria-disabled" , "true" ) ;
269273 inputElement . blur ( ) ;
270-
271- return ;
272274 }
273275 } ) ;
274276}
0 commit comments