我正在做一个涉及打字速度测试的练习。我添加了一个调色板,如果字符与测试文本匹配,则整个文本为绿色,如果不匹配则为红色。
如果我想要改变个性角色,我能想到的所有方式看起来都很乏味。我每次输入一个字符时都尝试创建单独的span
标记,并将它们分配给文本字符串的数组值,但却无法使其工作。有没有更有效的方法来做到这一点,或者我现在的方法是“最好的”方式呢?
我更倾向于采用一般途径来解决这个问题,而不是只写出一个完整的解决方案,所以我可以自己写出来。
const testWrapper = document.querySelector(".test-wrapper");
const testArea = document.querySelector("#test-area");
const originText = document.querySelector("#origin-text p").innerHTML;
const resetButton = document.querySelector("#reset");
const theTimer = document.querySelector(".timer");
var interval;
var timer = [0,0,0,0];
var timerRunning = false;
// Add leading zero to numbers 9 or below (purely for aesthetics):
function leadingZero(time) {
if (time <= 9) {
time = "0" + time;
}
return time;
}
// Run a standard minute/second/hundredths timer:
function runTimer() {
let currentTime = leadingZero(timer[0]) + ":" + leadingZero(timer[1]) + ":" + leadingZero(timer[2]);
theTimer.innerHTML = currentTime;
timer[3]++;
timer[0] = Math.floor((timer[3]/100)/60);
timer[1] = Math.floor((timer[3]/100) - (timer[0] * 60));
timer[2] = Math.floor(timer[3] - (timer[1] * 100) - (timer[0] * 6000));
}
// Match the text entered with the provided text on the page:
function spellCheck() {
let textEntered = testArea.value;
let originTextMatch = originText.substring(0,textEntered.length);
if (textEntered == originText) {
testWrapper.style.borderColor = "#429890";
clearInterval(interval);
} else {
if (textEntered == originTextMatch) {
testWrapper.style.borderColor = "#65ccf3";
testArea.style.color = "#00B400";
} else {
testWrapper.style.borderColor = "#e95d0f";
testArea.style.color = "#FF0000"
}
}
}
// Start the timer:
function start() {
let textEnteredLength = testArea.value.length;
if(textEnteredLength === 0 && !timerRunning) {
timerRunning = true;
interval = setInterval(runTimer, 10);
}
}
// Reset everything:
function reset(){
timer = [0,0,0,0];
theTimer.innerHTML = "00:00:00";
clearInterval(interval);
testArea.value = "";
timerRunning = false;
console.log("The reset button has been pressed.");
}
// Event listeners for keyboard input and the reset button:
testArea.addEventListener("keypress", start, false);
testArea.addEventListener("keyup", spellCheck, false);
resetButton.addEventListener("click", reset, false);
/*--------------------------------------------------------------
Typography
--------------------------------------------------------------*/
body,
button,
input,
select,
textarea {
font-family: 'Source Sans Pro', 'Helvetica', Arial, sans-serif;
font-size: 18px;
line-height: 1.5;
}
h1,
h2,
h3,
h4,
h5,
h6 {
clear: both;
}
p {
margin-bottom: 1.5em;
}
b,
strong {
font-weight: bold;
}
dfn,
cite,
em,
i {
font-style: italic;
}
blockquote {
margin: 0 1.5em;
}
address {
margin: 0 0 1.5em;
}
pre {
background: #eee;
font-family: "Courier 10 Pitch", Courier, monospace;
font-size: 15px;
font-size: 1.5rem;
line-height: 1.6;
margin-bottom: 1.6em;
max-width: 100%;
overflow: auto;
padding: 1.6em;
}
code,
kbd,
tt,
var {
font: 15px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
}
abbr,
acronym {
border-bottom: 1px dotted #666;
cursor: help;
}
mark,
ins {
background: #fff9c0;
text-decoration: none;
}
sup,
sub {
font-size: 75%;
height: 0;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
bottom: 1ex;
}
sub {
top: .5ex;
}
small {
font-size: 75%;
}
big {
font-size: 125%;
}
/*--------------------------------------------------------------
Layout
--------------------------------------------------------------*/
body {
margin: 0;
padding: 0;
}
.masthead {
padding: 1em 2em;
background-color: #0D1B2E;
color: white;
}
.masthead h1 {
text-align: center;
}
.intro {
padding: 2em 2em;
color: #ffffff;
background: #429890;
}
.intro p,
.test-area {
margin: 0 auto;
max-width: 550px;
}
.test-area {
margin-bottom: 4em;
padding: 0 2em;
}
.test-wrapper {
border: 10px solid grey;
border-radius: 10px;
}
#origin-text {
margin: 1em 0;
padding: 1em 1em 0;
background-color: #ededed;
}
#origin-text p {
margin: 0;
padding-bottom: 1em;
}
.test-wrapper {
display: flex;
}
.test-wrapper textarea {
flex: 1;
}
.meta {
margin-top: 1em;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.timer {
font-size: 3em;
font-weight: bold;
}
#reset {
padding: .5em 1em;
font-size: 1.2em;
font-weight: bold;
color: #E95D0F;
background: white ;
border: 10px solid #E95D0F;
}
#reset:hover {
color: white;
background-color: #E95D0F;
}
<header class="masthead">
<h1>Test Your Typing Speed</h1>
</header>
<main class="main">
<article class="intro">
<p>This is a typing test. Your goal is to duplicate the provided text, EXACTLY, in the field below. The timer starts when you start typing, and only stops when you match this text exactly. Good Luck!</p>
</article><!-- .intro -->
<section class="test-area">
<div id="origin-text">
<p>The text to test.</p>
</div><!-- #origin-text -->
<div class="test-wrapper">
<textarea id="test-area" name="textarea" rows="6" placeholder="The clock starts when you start typing."></textarea>
</div><!-- .test-wrapper -->
<div class="meta">
<section id="clock">
<div class="timer">00:00:00</div>
</section>
<button id="reset">Start over</button>
</div><!-- .meta -->
</section><!-- .test-area -->
</main>
答案 0 :(得分:0)
如果效率是你的问题,我会说使用一个MVVM框架,如KnockoutJS或Angular,那么它很容易确定差异并保持代码真正干净。
我将文本拆分为两个并排: 1.文字输入| 2.要复制的文本
使用单独的框输入。
你可以减去按键时键入的内容,可能是基于字符串长度,从2.text复制,并将其输入1.text类型。
使用计算出的方法确定它是否匹配,并相应地在1.text类型上设置类。