一、需求分析
1.点击出题按钮开始倒计时60秒,同时随机生成题目
2.每次出题20道,且题目中的数据和运算符皆是随机生成的
3.倒计时60秒结后,弹出提示框,提示答题已结束,并在显示答题情况
4.每道提供一个用于输入答案的文本框,用于输入答案,输入答案后,点击提交按钮,显示对,错以及未填,但不显示正确答案
二、项目搭建
创建项目,并在项目根目录文件下创建存放资源的对应文件夹以及HTML文件index.html
CSS:用于存放项目的CSS文件
img:用于存放项目的图片
JS:用于存放项目的JS文件
如图所示:
由于项目使用到了JQuery框架,所以需要在项目的JS文件夹中引入JQuery的JS文件
同时创建用于存放页面JS代码的index.js
如图所示:
官网下载地址:jQuery
进入首页,点击Download
选择下载:Download the uncompressed, development jQuery 3.7.0
在新打开的页面,同时按住Ctrl和 S,或者在空白处右击,选择另存为,在弹出的弹窗内,选择保存路径,将JS文件保存到本地
三、构建页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
//引入JQuery框架的JS文件
<script type="text/javascript" charset="UTF-8" src="./JS/jquery-3.7.0.js"></script>
//引入页面的JS文件
<script type="text/javascript" charset="UTF-8" src="js/index.js"></script>
//编写样式,美化页面
<style>
#content {
width: 800px;
margin: 0 auto;
text-align: center;
}
#tbl_count {
margin: 20px 0px;
}
.div_result {
margin: 10px 0px;
}
</style>
</head>
<body>
<div id="content">
//标题
<h1>20以内加减运算辅助工具</h1>
//倒计时
<h3 id="txt_time">60秒倒计时:60</h3>
//出题按钮
<button type="button" id="btnStart">出题</button>
//表格,由于题目是由JS代码控制,随机出题,所以页面中只需要编写表头部分的代码
<table id="tbl_count" width="800px" border="1px" cellpadding="5px" cellspacing="0px">
<tr>
<th>编号</th>
<th>计算题</th>
<th>你的答案</th>
<th>提交答案</th>
<th>结果</th>
</tr>
</table>
//显示答题情况
<div class="div_result" id="div_correct">答对:</div>
<div class="div_result" id="div_error">答错:</div>
<div class="div_result" id="div_empty">未答:</div>
</div>
</body>
</html>
页面效果如图所示:
四、编写JS功能代码
1.定义变量
//定义变量用于保存setInterval()方法返回的计时器对象ID
var interwork;
//定义变量存放答题情况
var correct = 0;
var error = 0;
var empty = 0;
//定义变量存放结果
var result;
2.倒计时
想要实现倒计时的效果,就不得不提到计时器了
什么是计时器?
计时器是一种在特定时间间隔内重复执行某个代码块的机制,它可以通过设置时间间隔来控制代码的执行频率,从而实现一些动态效果。
在jQuery中,有两种常用的计时器函数:setInterval()和setTimeout()。
- setInterval():会按照指定的时间间隔重复执行代码块,直到被取消。
- setTimeout():会在指定的时间间隔后执行代码块,只执行一次。
在本次的项目中,采用setInterval()函数来进行倒计时功能的实现
基本语法
setInterval(function, milliseconds, param1, param2, ...)
参数说明
- function:必需,要重复执行的函数或代码块。
- milliseconds:必需,重复执行的时间间隔(以毫秒为单位)。
- param1, param2, ...:可选,传递给要执行的函数的参数。如果无须传递参数,则省略此参数。
clearInterval()函数
那么在启动计时器之后,60秒倒计时结束,我们则需要停止计数,这时,就需要使用到另一个函数——clearInterval()
setInterval() 方法会返回一个计时器ID,在定义变量的时候,我们也定义interwork变量用来存放这个ID
有了clearInterval()函数以及计时器的ID,我们就可以通过调用clearInterval()函数,取消计时器的执行
功能实现
倒计时的启动是通过出题按钮来进行控制的,所以我们需要将计时器放置在出题按钮的单击事件中
代码如下
//出题按钮的单击事件
$("#btnStart").click(function() {
//停止计时器
clearInterval(interwork);
//定义变量控制倒计时
var timenum = 60;
//倒计时
interwork = window.setInterval(function() {
//时间变量自减
timenum--;
//判断当时间为0时,提示并停止计时器
if (timenum == 0) {
alert("倒计时结束")
clearInterval(interwork);
}
//更新时间显示
$("#txt_time").html("60秒倒计时:" + timenum);
// 每一秒更新一次时间,时间单位为ms
}, 1000);
});
3.出题
根据需求分析可知,所有的题目是在点击出题按钮后,一次性出完全部的20道题目,且20道题目的数字和运算符完全随机
点击按钮,出完全部题目这一功能,可以采用在出题按钮的单击事件中,使用for循环,循环20次,以此来完成一次性出题20道的需求
而题目数字以及运算符的随机生成,则有两种可供选择:
- Math类的random()方法
- Random类
Math类的random()方法
Math类的random()方法可以生成大于等于0.0、小于1.0的double型伪随机数,即 0 <= Math.random() < 1.0
虽然Math.random()方法只可以产生0 ~ 1之间的double型数字,其实只要在Math.random()方法语句基础上进行处理,就可以获得多种类型、或任意范围的随机数。
例如:
int num=(int)(Math.random()*n); //返回大于等于0小于n之间的随机数
int num0=m+(int)(Matn.randon()*n); //返回大于等于m小于m+n(不包括m+n)之间的随机数
除此之外,还可以随机生成字符
例如:
1.随机生成a~z之间的字符
(char)('a'+Math.random()*('z'-'a'+1));
2.随机生成cha1~cha2的字符
(char)(cha1+Math.random()*(cha2-cha1+1));
Random类
除了使用Math类的Random()方法可以获取随机数之外,还可以使用Java.util.Random类,通过实例化一个Random对象创建一个随机数生成器
语法
Random ran=new Random();
Random类的实例对象以这种形式实例化对象时,Java编译器以系统当前时间作为随机数生成器的种子,因为每时每刻的时间都不可能相同,所以产生的随机数也不同。如果运行速度太快,也会产生两次运行结果相同的随机数
可以在实例化Random类对象时,自定义随机数生成器的种子
语法
Random ran=new Random(seedValue);
Random类中还提供各种类型随机数的方法:
- nextInt():返回一个随机整数(int)
- nextInt(int n):返回大于等于0、小于n的随机整数(int)
- nextLong():返回一个随机长整型值(long)
- nextBoolean():返回一个随机布尔型值(boolean)
- nextFloat():返回一个随机浮点型值(float)
- nextDouble():返回一个随机双精度型值(double)
- nextGaussian():概率密度为高斯分布的双精度值(double)
定义随机数
根据需求可以得知,我们共需要三个随机数:两个数字和一个运算符
在本次的案例中,使用Math类的random()方法进行随机数的生成
代码如下:
var num1 = Math.random();
var num2 = Math.random();
Math类的random()方法只产生0 ~ 1之间的double型数字,所以我们需要乘以20,将范围拓展到0-20
但是我们需要的是0-20之间的整数,所以使用parseInt函数,将小数转化成整数(parseInt向下取整)
var num1 = parseInt(Math.random() * 20);
var num2 = parseInt(Math.random() * 20);
而运算符的随机生成,只是从加号和减号中随机选择一个
所以这时,就需要定义一个字符串类型的数组
var arr = ["+", "-"];
然后使用Math类的random()方法乘以数组长度,获取0到数组长度的数据作为下标,以此来获取数组中的数据
var fhindex = parseInt(Math.random() * arr.length);
有了三个随机数,就可以结合for循环来实现出题的功能(该段代码用于测试,故只循环五次)
for (var i = 1; i <= 5; i++) {
//生成两个随机数
var num1 = parseInt(Math.random() * 20);
var num2 = parseInt(Math.random() * 20);
//生成随机运算符
var arr = ["+", "-"];
var fhindex = parseInt(Math.random() * arr.length);
//创建内容
var id = $("<td></td>").html(i);
var title = $("<td></td>").html(
"<span id='num1'>" + num1 + "</span><span id='fh'>" + arr[fhindex] +
"</span><span id='num2'>" + num2 + "</span>");
var answer = $("<td></td>").html("<input type='text' class='txt_answer'>");
var submit = $("<td></td>").html(
"<button type='button' class='btn_sub' id='btn_submit" + i + "'>提交</button>");
var result = $("<td></td>").html("<span class='result'></span>");
var textnode = $("<tr></tr>").append(id, title, answer, submit, result);
//加入表格
$("#tbl_count").append(textnode);
}
4.答题
在完成出题,就可以开始答题了,在点击提交按钮后,将文本框中输入的答案和正确答案进行比较,并在表格最后一列,显示答题结果
这就需要根据所点击的按钮,获取到该行中的题目中的数字和运算符,以及文本框中输入的答案
然后定义变量用于存放正确答案,并根据获取到的运算符进行计算
最后将计算的结果和文本框中输入的结果进行对比,并改变结果的显示文字
代码如下:
$('#tbl_count').on('click', '.btn_sub', function() {
//获取所点击行的数字和符号
var num1 = $(this).closest('tr').find('td #num1').text();
var fh = $(this).closest('tr').find('td #fh').text();
var num2 = $(this).closest('tr').find('td #num2').text();
//获取输入的答案
var answer = $(this).closest('tr').find('td .txt_answer').val();
//定义变量存放结果
var result;
//计算
if (fh == "+") {
result = parseInt(num1) + parseInt(num2);
}
if (fh == "-") {
result = parseInt(num1) - parseInt(num2);
}
//判断是否回答正确
if (parseInt(answer) == result) {
$(this).closest('tr').find('td .result').text("对");
correct++;
}
if (parseInt(answer) != result && answer != "") {
$(this).closest('tr').find('td .result').text("错");
error++;
}
if (answer == "") {
$(this).closest('tr').find('td .result').text("未填");
empty++;
}
});
除了对比答案,显示答题结果以外,还需要对答题情况进行统计,并在计时器停止,将答题情况显示在页面上的相应位置
这时,我们就需要对计时器停止的功能进行修改
代码如下:
//判断当时间为0时,提示并停止计时器
if (timenum == 0) {
alert("倒计时结束")
clearInterval(interwork);
//判断是否有为空的文本框,若为空则全部算为未填
$(".txt_answer").each(function() {
if ($.trim($(this).val()).length == 0) {
empty++;
}
});
//统计对错的数量
$(".result").each(function() {
if ($(this).text() == "对") {
correct++;
}
if ($(this).text() == "错") {
error++;
}
});
//显示答题情况
$("#div_correct").html("答对:" + correct);
$("#div_error").html("答错:" + error);
$("#div_empty").html("未答:" + empty);
}
至此,整个案例的功能已经全部完成
5.完善
仅仅是功能的完成,并不能代表着案例的结束,还需要基于现有代码,对整个案例进行完善
比如:
在倒计时结束后,不光对答题情况进行统计,也可以将答案输入框和提交按钮,设为禁用
在开始第二次练习时,也就是再次单击出题按钮后,需要将存放答题情况的三个变量清空,以及上一次练习的题目清空
代码如下:
//倒计时结束设置文本框为禁用状态
$(".txt_answer").prop("disabled", true);
$(".btn_sub").prop("disabled", true);
//清空答题情况(将三个变量重新赋值为0)
correct = 0;
error = 0;
empty = 0;
//清空练习的题目(清空表格内除表头外的所有内容)
$("#tbl_count tr:not(:first)").empty();
6.优化
在测试过程中发现,在输入答案后,点击提交按钮将答案进行提交,这一操作过于繁琐
对此,可将其改成文本框的获取焦点(focus)和失去焦点(focusout)的事件,来完成这一功能
其思路与使用按钮进行提交大致相同,仅进行代码展示
代码如下:
//定义变量存放结果
var result;
$('#tbl_count').on('focus', '.txt_answer', function() {
//获取所点击行的数字和符号
var num1 = $(this).closest('tr').find('td #num1').text();
var fh = $(this).closest('tr').find('td #fh').text();
var num2 = $(this).closest('tr').find('td #num2').text();
//计算
if (fh == "+") {
result = parseInt(num1) + parseInt(num2);
}
if (fh == "-") {
result = parseInt(num1) - parseInt(num2);
}
});
$('#tbl_count').on('focusout', '.txt_answer', function() {
//获取输入的答案
var answer = $(this).closest('tr').find('td .txt_answer').val();
//判断是否回答正确,并显示结果
if (parseInt(answer) == result) {
$(this).closest('tr').find('td .result').text("对");
}
if (parseInt(answer) != result && answer != "") {
$(this).closest('tr').find('td .result').text("错");
}
if (answer == "") {
$(this).closest('tr').find('td .result').text("未填");
}
});