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 相关文章推荐
javascript 单例/单体模式(Singleton)
Apr 07 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
Aug 05 Javascript
深入探寻seajs的模块化与加载方式
Apr 14 Javascript
Jquery EasyUI实现treegrid上显示checkbox并取选定值的方法
Apr 29 Javascript
浅析JavaScript中的对象类型Object
May 26 Javascript
一个简单不报错的summernote 图片上传案例
Jul 11 Javascript
AngularJS中使用ngModal模态框实例
May 27 Javascript
激动人心的 Angular HttpClient的源码解析
Jul 10 Javascript
React-Native左右联动List的示例代码
Sep 21 Javascript
JS表格的动态操作完整示例
Jan 13 Javascript
微信小程序完美解决scroll-view高度自适应问题的方法
Aug 08 Javascript
Vue实现指令式动态追加小球动画组件的步骤
Dec 18 Vue.js
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
用PHP实现小型站点广告管理(修正版)
2006/10/09 PHP
phpmyadmin中配置文件现在需要绝密的短语密码的解决方法
2007/02/11 PHP
PHP 长文章分页函数 带使用方法,不会分割段落,翻页在底部
2009/10/22 PHP
PHP提取字符串中的图片地址[正则表达式]
2011/11/12 PHP
php 获取SWF动画截图示例代码
2014/02/10 PHP
PHP读书笔记整理_结构语句详解
2016/07/01 PHP
PHP序列化操作方法分析
2016/09/28 PHP
setTimeout函数兼容各主流浏览器运行执行效果实例
2013/06/13 Javascript
Jquery实现自定义窗口随意的拖拽
2014/03/12 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
详解浏览器渲染页面过程
2017/02/09 Javascript
微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
2017/08/16 Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
2017/08/28 Javascript
轻松理解vue的双向数据绑定问题
2017/10/30 Javascript
vue按需加载组件webpack require.ensure的方法
2017/12/13 Javascript
在vue中使用公共过滤器filter的方法
2018/06/26 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
详解Vue的ref特性的使用
2020/01/24 Javascript
js实现鼠标滑动到某个div禁止滚动
2020/09/17 Javascript
[34:39]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#1COL VS EG第二局
2016/03/05 DOTA
python3 发送任意文件邮件的实例
2018/01/23 Python
利用nohup来开启python文件的方法
2019/01/14 Python
解决Python内层for循环如何break出外层的循环的问题
2019/06/24 Python
pytest中文文档之编写断言
2019/09/12 Python
使用Python实现Wake On Lan远程开机功能
2020/01/22 Python
纯CSS3实现Material Design效果
2017/03/09 HTML / CSS
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
2017/01/05 HTML / CSS
html5 canvas 实现光线沿不规则路径运动
2020/04/20 HTML / CSS
End Clothing美国站:英国男士潮牌商城
2018/04/20 全球购物
个人找工作求职简历的自我评价
2013/10/20 职场文书
期末自我鉴定
2014/01/23 职场文书
人力资源管理专业应届生求职信
2014/04/24 职场文书
培根随笔读书笔记
2015/07/01 职场文书
Mysql中 unique列插入重复值该怎么解决呢
2021/05/26 MySQL
Python echarts实现数据可视化实例详解
2022/03/03 Python
Win10 heic文件怎么打开 ? Win10 heic文件打开教程
2022/04/06 数码科技