JS实现电脑虚拟键盘打字测试


Posted in Javascript onJune 24, 2020

这篇blog主要是结合前面两个知识点:JS实现电脑虚拟键盘的操作、JS实现简单打字测试

实现的效果如下:

JS实现电脑虚拟键盘打字测试

具体代码如下:

Html部分:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <link rel="stylesheet" href="./index.css" >
 <link rel="stylesheet" href="./keyBoard..css" >
 <title>打字测试</title>
</head>

<body>
 <div class="type_content">
  <h3>打字测试</h3>
  <ul class="type_box">
   <li class="error_box">
    <p class="error">错误</p>
    <p class="error_text">0</p>
   </li>
   <li class="time_box">
    <p style="margin: 10px;">时间</p>
    <p class="time_text">60s</p>
   </li>
   <li class="currcorrect_box">
    <p style="margin: 10px;">当前准确率%</p>
    <p class="currcorrect_text">100</p>
   </li>
   <li class="type_speed">
    <p style="margin: 10px;">打字速度</p>
    <p class="type_speed_text">30个/分</p>
   </li>
  </ul>
  <div class="text_box">点击下放文本输入框开始打字!!!</div>
  <div class="text_area">
  <textarea name="" id="textarea_box" placeholder="start typing here..."> </textarea>
  </div>
  <button class="restart" onclick="resetValues()">重新开始</button>
 </div>
 <div class="keyBoard">
 
 </div>
 <script src="./jquery-1.11.0.min.js"></script>
 <script src="./index.js"></script>
 <script src="./keyBoard.js"></script>

</body>

</html>

index.css:

*{
 margin: 0;
 padding: 0;
}
.type_content{
 width: 60%;
 /* height: 440px; */
 border: 1px solid #ccccff;
 max-width: 600px;
 margin: 10px auto;
 border-radius: 8px;
 position: relative;
 min-width: 500px;
}
.type_content h3{
 text-align: center;
 margin: 10px 0px;
}
.type_box{
 list-style: none;
 width: 90%;
 height: 100px;
 /* border: 1px solid black; */
 margin: 0 auto;
 margin-bottom: 10px;
 display: flex;
 align-items: center;
 justify-content: space-around;
}
.type_box li{
 width: 88px;
 height: 88px;
 /* border: 1px solid black; */
 text-align: center;
 font-size: 16px;
 border-radius: 8px;
 /* color: #fff; */
}
.error_box{
 background-color: #ccffcc;
 color: red;
}
.time_box{
 background-color: #66ffff;
 color: #000033;
}
.currcorrect_box{
 background-color: #FFC125;
 color: #fff;
}
.type_speed{
 background-color: #FF4040;
 color: #fff;
 display: none;
}
.final_correct{
 background-color: #E3E3E3;
 color: #555555;
 display: none;
}
.error{
 margin: 10px;
}
.text_box{
 width: 80%;
 /* height: 50px; */
 margin: 20px auto 40px auto;
 /* border: 1px solid black; */
 background-color: #D1EEEE;
 color: #000;
 border-radius: 6px;
 /* text-align: center; */
 line-height: 40px;
 padding: 0px 5px;
 /* box-sizing: border-box; */
}
.text_area{
 width: 80%;
 height: 50px;
 margin: 0px auto;
 padding-bottom: 50px;
 margin-bottom: 30px;
 
}
#textarea_box{
 resize:none;
 width: 100%;
 height: 100%;
 padding: 6px 10px;
 font-size: 16px;
 border-radius: 6px;
 outline: none;
 border: none;
 border: 2px solid #eee;
} 
.incorrect_char { 
 color: red; 
 text-decoration: underline; 
 } 
 
 .correct_char { 
 color: #9B30FF; 
 }
 .restart{
  width: 120px;
  height: 40px;
  display: none;
  border: none;
  outline: none;
  cursor: pointer;
  color: #fff;
  background-color: #9900ff;
  border-radius: 6px;
  position: absolute;
  bottom: 10px;
  left: 50%;
  margin-left: -60px;
  
}

keyboard.css:

/* body * {
 margin: 0;
 padding: 0;
 box-sizing: border-box;
 font-family: Arial, Helvetica, sans-serif;
} */
.keyBoard{
 max-width: 800px;
 padding: 20px;
 position: absolute;
 /* top: 50%;
 left: 50%;
 transform: translate(-50%, -50%); */
 background-color: rgb(197, 197, 197);
 border-radius: 10px;
 display: none;
 grid-template-columns: repeat(30, 20px);
 grid-template-rows: repeat(5, 30px);
 grid-gap: 5px;
 margin-left: 20%;

}
.key {
 background-color: rgb(243, 243, 243);
 border: 2px solid black;
 border-radius: 5px;
 grid-column: span 2;
 font-size: 12px;
 text-align: center;
 /* padding-top: 17px; */
 cursor: pointer;
 line-height: 30px;
 font-weight: 700;
}

.key:hover {
 border: 1px solid #eeeeee;
 
 
}

.backspace {
 grid-column: span 4;
}

.tab {
 grid-column: span 3;
}

.backslash {
 grid-column: span 3;
}

.capslock {
 grid-column: span 4;
}

.enter {
 grid-column: span 4;
}

.leftshift {
 grid-column: span 5;
}

.rightshift {
 grid-column: span 5;
}

.leftctrl {
 grid-column: span 3;
}

.microsoft {
 grid-column: span 3;
 font-size: 14px;
 
}

.space {
 grid-column: span 13;
}
.input_box{
 width: 400px;
 height: 60px;
 /* border: 1px solid black; */
 margin: auto;
 margin-top: 100px;
}
.input_box input{
 outline: none;
 border: none;
 width: 100%;
 height: 100%;
 border: 2px solid #ccc;
 border-radius: 8px;
 padding: 10px;
 font-size: 30px;
}

index.js:

//定义测试时间
var testTime = 60;
//定义测试的句子
var testSentence = [
 "Push yourself, because no one else is going to do it for you.",
 "Failure is the condiment that gives success its flavor.",
 // "Wake up with determination. Go to bed with satisfaction.",
 // "It's going to be hard, but hard does not mean impossible.",
 // "Learning never exhausts the mind.",
 // "The only way to do great work is to love what you do."
]
//定义dom
//1.错误dom
var error_text = document.querySelector('.error_text');
//2.时间dom
var time_text = document.querySelector('.time_text');
//3.当前正确率
var currcorrect_text = document.querySelector('.currcorrect_text');
//4.打字速度
var type_speed_text = document.querySelector('.type_speed_text');

//打字速度父dom
var type_speed = document.querySelector('.type_speed');


//句子dom
var text_box = document.querySelector('.text_box');
//输入
var textarea_box = document.querySelector('#textarea_box');
//按钮
var restart = document.querySelector('.restart')
var timeLeft = testTime;
//当前句子
var currentSentence = "";
//默认开始是索引为0
var startIndex = 0;
//错误统计
var errors = 0;
var characterTyped = 0;
//总错误
var total_errors = 0; 
var timer = null;
var timeElapsed = 0; //已用时间
var accuracy = 0;//正确个数
//更新渲染句子
function updateSentence(){
 text_box.textContent = null;
 currentSentence = testSentence[startIndex];
 //句子拆分
 var newChar = currentSentence.split('');
 for(var i = 0; i < newChar.length; i++){
  var charSpan = document.createElement('span');
  charSpan.innerText = newChar[i];
  text_box.appendChild(charSpan)
 }
 if(startIndex < testSentence.length - 1){
  startIndex++;
 }else{
  startIndex = 0
 }
}
//输入当前正确的句子
function processCurrentText(){
 curr_input = textarea_box.value;
 curr_input_array = curr_input.split('');
 // console.log(curr_input_array);
 characterTyped++;
 errors = 0;
 quoteSpanArray = text_box.querySelectorAll('span');
 // console.log(quoteSpanArray);
 quoteSpanArray.forEach((char,index)=>{
  var typeChar = curr_input_array[index];
  //当前没有输入
  if(typeChar == null){
   char.classList.remove('correct_char'); 
   char.classList.remove('incorrect_char'); 
  }else if(typeChar === char.innerText){
   //正确的输入
   char.classList.add('correct_char'); 
   char.classList.remove('incorrect_char'); 
  }else{
   //不正确的输入
   char.classList.add('incorrect_char'); 
    char.classList.remove('correct_char');
    errors++; 
  }
 })
 error_text.textContent = total_errors + errors; 
 console.log(characterTyped)
 console.log(error_text.textContent)
 var correctCharacters = (characterTyped - (total_errors + errors)); 
 var accuracyVal = ((correctCharacters / characterTyped) * 100); 
 console.log(accuracyVal)
 currcorrect_text.textContent = Math.round(accuracyVal); 
 //输入结束
 if(curr_input.length == currentSentence.length){
  updateSentence(); 
  total_errors += errors; 
  textarea_box.value = ""
 }
}
//开始游戏
function startGame(){
 resetValues(); 
 updateSentence(); 
 
 // clear old and start a new timer 
 clearInterval(timer); 
 timer = setInterval(updateTimer, 1000); 
}
//重新开始
function resetValues(){
 timeLeft = testTime;
 timeElapsed = 0;
 errors = 0;
 total_errors = 0;
 accuracy = 0;
 characterTyped = 0;
 startIndex = 0;
 textarea_box.disabled = false;
 textarea_box.value = "";
 text_box.textContent = 'Click on the area below to start the game.'; 
 currcorrect_text.textContent = 100;
 time_text.textContent = timeLeft + 's';
 type_speed.style.display = 'none';
 
}
//更新时间
function updateTimer() { 
 if (timeLeft > 0) { 
  // decrease the current time left 
  timeLeft--; 
 
  // increase the time elapsed 
  timeElapsed++; 
 
  // update the timer text 
  time_text.textContent = timeLeft + "s"; 
 } 
 else { 
  // finish the game 
  finishGame(); 
 } 
 } 
 //游戏结束
 function finishGame() { 
 // stop the timer 
 clearInterval(timer); 
 
 // disable the input area 
 textarea_box.disabled = true; 
 
 // show finishing text 
 text_box.textContent = "可点击下方按钮重新开始!!!"; 
 
 // display restart button 
 restart.style.display = "block"; 
 
 // calculate cpm and wpm 
 console.log(characterTyped,timeElapsed)
 cpm = Math.round(((characterTyped / timeElapsed) * 60)); 
 
 // update cpm and wpm text 
 
 type_speed_text.textContent = cpm + '个/分'; 
 
 // display the cpm and wpm 
 type_speed.style.display = "block"; 
 
 }

keyboard.js:

var keyArray = [
 { 'key_name': '`', 'key_val': '192' },
 { 'key_name': '1', 'key_val': '49' },
 { 'key_name': '2', 'key_val': '50' },
 { 'key_name': '3', 'key_val': '51' },
 { 'key_name': '4', 'key_val': '52' },
 { 'key_name': '5', 'key_val': '53' },
 { 'key_name': '6', 'key_val': '54' },
 { 'key_name': '7', 'key_val': '55' },
 { 'key_name': '8', 'key_val': '56' },
 { 'key_name': '9', 'key_val': '57' },
 { 'key_name': '0', 'key_val': '48' },
 { 'key_name': '-', 'key_val': '189' },
 { 'key_name': '=', 'key_val': '187' },
 { 'key_name': 'Backspace', 'key_val': '8' },

 { 'key_name': 'Tab', 'key_val': '9' },
 { 'key_name': 'Q', 'key_val': '81' },
 { 'key_name': 'W', 'key_val': '87' },
 { 'key_name': 'E', 'key_val': '69' },
 { 'key_name': 'R', 'key_val': '82' },
 { 'key_name': 'T', 'key_val': '84' },
 { 'key_name': 'Y', 'key_val': '89' },
 { 'key_name': 'U', 'key_val': '85' },
 { 'key_name': 'I', 'key_val': '73' },
 { 'key_name': 'O', 'key_val': '79' },
 { 'key_name': 'P', 'key_val': '80' },
 { 'key_name': '[', 'key_val': '219' },
 { 'key_name': ']', 'key_val': '221' },
 { 'key_name': "\\ ", 'key_val': '220' },

 { 'key_name': 'CapsLock', 'key_val': '20' },
 { 'key_name': 'A', 'key_val': '65' },
 { 'key_name': 'S', 'key_val': '83' },
 { 'key_name': 'D', 'key_val': '68' },
 { 'key_name': 'F', 'key_val': '70' },
 { 'key_name': 'G', 'key_val': '71' },
 { 'key_name': 'H', 'key_val': '72' },
 { 'key_name': 'J', 'key_val': '74' },
 { 'key_name': 'K', 'key_val': '75' },
 { 'key_name': 'L', 'key_val': '76' },
 { 'key_name': ';', 'key_val': '186' },
 { 'key_name': "'", 'key_val': '222' },
 { 'key_name': 'Enter', 'key_val': '13' },

 { 'key_name': 'Shift', 'key_val': '16' },
 { 'key_name': 'Z', 'key_val': '90' },
 { 'key_name': 'X', 'key_val': '88' },
 { 'key_name': 'C', 'key_val': '67' },
 { 'key_name': 'V', 'key_val': '86' },
 { 'key_name': 'B', 'key_val': '66' },
 { 'key_name': 'N', 'key_val': '78' },
 { 'key_name': 'M', 'key_val': '77' },
 { 'key_name': ',', 'key_val': '188' },
 { 'key_name': '.', 'key_val': '190' },
 { 'key_name': '/', 'key_val': '191' },
 { 'key_name': 'Shift', 'key_val': '16' },

 { 'key_name': 'Ctrl', 'key_val': '17' },
 { 'key_name': 'Alt', 'key_val': '18' },
 { 'key_name': 'Home', 'key_val': '36 ' },
 { 'key_name': 'Space', 'key_val': '32' },
 { 'key_name': 'Home', 'key_val': '36' },
 { 'key_name': 'Alt', 'key_val': '18' },
 { 'key_name': 'Ctrl', 'key_val': '17' },
 { 'key_name': 'Fn', 'key_val': '00' },

]
var keyBoard = document.getElementsByClassName('keyBoard')[0]
function renderKeyBoard(keyArray) {
 var template = '';
 for (var i = 0; i < keyArray.length; i++) {
  if (keyArray[i].key_val == '8') {
   template += "<div class='key backspace' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '9') {
   template += "<div class='key tab' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '220') {
   template += "<div class='key backslash' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '20') {
   template += "<div class='key capslock' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '13') {
   template += "<div class='key enter' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '16') {
   template += "<div class='key leftshift' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '16') {
   template += "<div class='key rightshift' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '17') {
   template += "<div class='key leftctrl' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  } else if (keyArray[i].key_val == '36') {
   template += "<div class='key microsoft' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  }
  else if (keyArray[i].key_val == '32') {
   template += "<div class='key space' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  }
  else {
   template += "<div class='key' data-key='" + keyArray[i].key_val + "'>" + keyArray[i].key_name + "</div>";
  }


 }
 // console.log(template)
 keyBoard.innerHTML = template;
}
renderKeyBoard(keyArray)
var key_div = document.getElementsByClassName('key');
// console.log(key_div)
$("#textarea_box").on("input", function (e) {
 // console.log(e.keyCode)
 keyBoard.style.display = 'grid'
 processCurrentText()

});
$("#textarea_box").on("focus", function (e) {
 // console.log(e.keyCode)
 keyBoard.style.display = 'grid';
 startGame();

});
$("#textarea_box").on("keydown", function (e) {
  console.log(e.target.value)
 if(e.target.value != ''){
 for (var i = 0; i < key_div.length; i++) {
  var key_val = Number(key_div[i].getAttribute('data-key'));
  if (key_val === e.keyCode) {
   key_div[i].style.color = '#fff';
   key_div[i].style.backgroundColor = '#9F79EE'
  } else {
   key_div[i].style.color = ''
   key_div[i].style.backgroundColor = ''
  }
 }
 }

});
$("#textarea_box").on("keyup", function (e) {
 for (var i = 0; i < key_div.length; i++) {
  key_div[i].style.color = ''
  key_div[i].style.backgroundColor = ''
 }

});
$("#textarea_box").on("blur", function (e) {
 // console.log(e.keyCode)
 keyBoard.style.display = 'none'

});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery 学习笔记 选择器之六
Jul 23 Javascript
用js闭包的方法实现多点标注冒泡示例
May 29 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
Jun 02 Javascript
Bootstrap 轮播(Carousel)插件
Dec 26 Javascript
基于JavaScript实现购物车功能
Feb 07 Javascript
详谈js遍历集合(Array,Map,Set)
Apr 06 Javascript
vue select选择框数据变化监听方法
Aug 24 Javascript
详解mpvue小程序中怎么引入iconfont字体图标
Oct 01 Javascript
初学node.js中实现删除用户路由
May 27 Javascript
微信小程序动态设置图片大小的方法
Nov 21 Javascript
js实现中文实时时钟
Jan 15 Javascript
jQuery实现移动端下拉展现新的内容回弹动画
Jun 24 jQuery
JS实现简单打字测试
Jun 24 #Javascript
微信小程序实现多选框功能的实例代码
Jun 24 #Javascript
JS实现电脑虚拟键盘的操作
Jun 24 #Javascript
基于PHP pthreads实现多线程代码实例
Jun 24 #Javascript
js实现html滑动图片拼图验证
Jun 24 #Javascript
微信小程序的引导页实现代码
Jun 24 #Javascript
微信小程序仿抖音短视频切换效果的实例代码
Jun 24 #Javascript
You might like
支持php4、php5的mysql数据库操作类
2008/01/10 PHP
PHP 日志缩略名的创建函数代码
2010/05/26 PHP
php设计模式 Template (模板模式)
2011/06/26 PHP
php 中的4种标记风格介绍
2012/05/10 PHP
CI框架AR数据库操作常用函数总结
2016/11/21 PHP
在JavaScript中typeof的用途介绍
2013/04/11 Javascript
自动最大化窗口的Javascript代码
2013/05/22 Javascript
jQuery动画效果-fadeIn fadeOut淡入浅出示例代码
2013/08/28 Javascript
两个select多选模式的选项相互移动(示例代码)
2014/01/11 Javascript
浅析javascript 定时器
2014/12/23 Javascript
javascript中apply、call和bind的使用区别
2016/04/05 Javascript
Bootstrap3学习笔记(三)之表格
2016/05/20 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
js窗口震动小程序分享
2016/11/28 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
2017/04/17 Javascript
详解vue渲染函数render的使用
2017/12/12 Javascript
详解用Node.js写一个简单的命令行工具
2018/03/01 Javascript
使用 node.js 模仿 Apache 小部分功能
2019/07/07 Javascript
js实现简单的贪吃蛇游戏
2020/04/23 Javascript
[02:24]DOTA2痛苦女王 英雄基础教程
2013/11/26 DOTA
Python实现CET查分的方法
2015/03/10 Python
如何解决django-celery启动后迅速关闭
2019/10/16 Python
利用Python校准本地时间的方法教程
2019/10/31 Python
numpy 返回函数的上三角矩阵实例
2019/11/25 Python
解决import tensorflow as tf 出错的原因
2020/04/16 Python
浅谈CSS3中的变形功能-transform功能
2017/12/27 HTML / CSS
MyBag中文网:英国著名的时尚包袋电商零售网站
2020/07/31 全球购物
讲文明知礼仪演讲稿
2014/09/13 职场文书
老人再婚离婚协议书范本
2014/10/27 职场文书
2014年人力资源部工作总结
2014/11/19 职场文书
2014年流动人口工作总结
2014/11/26 职场文书
初中英语教师个人工作总结
2015/02/09 职场文书
社团招新宣传语
2015/07/13 职场文书
北京大学中文系教授推荐的10本小说
2019/08/08 职场文书
css3带你实现3D转换效果
2022/02/24 HTML / CSS