行业动态
手把手教你写考试系统小程序-前后端代码分享三
2024-02-14

前两篇文章讲到了试卷列表页面,手把手教你一个人开发小程序前后端(代码分享二)

本篇从代码上讲一下实现答题的逻辑,看效果

重播
播放
00:00 / 00:00 直播
00:00
进入全屏
50
点击按住可拖动视频

试卷中包含了单选,多选,判断题,小程序的代码设计如下

一、页面头部。当前第几题,总共多少题的,currentNumber从js实时计算

<view class="head" bindtap="showPopUp"> <image src="../../images/head_icon.png " /> <view class="question-number">{{currentNumber}}/{{allNumber}}</view> <view class="timer"> <text>{{min}}:{{sec}}</text>/<text>{{totalTime}}分钟</text> </view> </view>

进来后开始计时,时间到了自动提交答题记录的逻辑是怎么实现呢?

大致逻辑是,在onload时间中加载试题列表,获取到试题列表后开启计时器,代码如下

计时器代码逻辑如下 if (min == that.data.totalTime) { 这个判断逻辑实现了当计时时间跟试题时间一致时,触发提交答案的方法,同时关闭计时器。

/** * 计时器 */ timerSec: function () { var that = this; let sec = 0; let min = 0; let intervalsec = setInterval(function () { if (min == that.data.totalTime) { clearInterval(intervalsec); // 关闭计时器 // 提交答题结果 this.SubmitAnswer(); } sec++; if (sec == 60) { sec = 0; min++ that.setData({ min: min < 10 ? 0 + min : min }); } that.setData({ sec: sec < 10 ? 0 + sec : sec, intervalsec: intervalsec }); }, 1000); },

二,页面中部,试题布局和动态切换逻辑实现

页面中部是所有类型试题的渲染区域,具体代码如下,设计思路就是

绑定指定列表中的某个试题,根据试题类型进行对应的渲染,页面中包含了简答题和必答题的渲染,

<view class="body"> <view class="title" wx:if="{{list[indexFlag].ExamType!=}}"> <view wx:if="{{list[indexFlag].ExamType == 单选}}"> <view class="tag tagb">{{list[indexFlag].ExamType}}</view> </view> <view wx:if="{{list[indexFlag].ExamType == 多选}}"> <view class="tag tagg">{{list[indexFlag].ExamType}}</view> </view> <view wx:if="{{list[indexFlag].ExamType == 判断题}}"> <view class="tag tagp">{{list[indexFlag].ExamType}}</view> </view> <view wx:if="{{list[indexFlag].ExamType == 简答题}}"> <view class="tag tagc">{{list[indexFlag].ExamType}}</view> </view> <view wx:if="{{list[indexFlag].ExamType == 必答题}}"> <view class="tag tagd">{{list[indexFlag].ExamType}}</view> </view> <view wx:if="{{list[indexFlag].ExamType == 填空题}}"> <view class="tag tage">{{list[indexFlag].ExamType}}</view> </view> <view class="title-text">{{indexFlag+1}}.{{list[indexFlag].ExamContent}}</view> </view> <radio-group wx:if="{{list[indexFlag].ExamType!= && list[indexFlag].ExamType == 单选}}"> <view class="view" wx:if="{{list[indexFlag].OptionA != }}"> <radio bindtap="changeFlag" data-selectValue="a" checked="{{RadioAChecked}}"></radio> <view class="option-text">A、{{list[indexFlag].OptionA}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionB != }}"> <radio bindtap="changeFlag" data-selectValue="b" checked="{{RadioBChecked}}"></radio> <view class="option-text">B、{{list[indexFlag].OptionB}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionC != }}"> <radio bindtap="changeFlag" data-selectValue="c" checked="{{RadioCChecked}}"></radio> <view class="option-text">C、{{list[indexFlag].OptionC}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionD != }}"> <radio bindtap="changeFlag" data-selectValue="d" checked="{{RadioDChecked}}"></radio> <view class="option-text">D、{{list[indexFlag].OptionD}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionE != }}"> <radio bindtap="changeFlag" data-selectValue="e" checked="{{RadioEChecked}}"></radio> <view class="option-text">E、{{list[indexFlag].OptionE}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionF != }}"> <radio bindtap="changeFlag" data-selectValue="f" checked="{{RadioFChecked}}"></radio> <view class="option-text">F、{{list[indexFlag].OptionF}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionG != }}"> <radio bindtap="changeFlag" data-selectValue="g" checked="{{RadioGChecked}}"></radio> <view class="option-text">G、{{list[indexFlag].OptionG}}</view> </view> </radio-group> <radio-group wx:if="{{list[indexFlag].ExamType!= && list[indexFlag].ExamType == 判断题}}"> <view class="view" wx:if="{{list[indexFlag].OptionA != }}"> <radio bindtap="changeFlag" data-selectValue="a" checked="{{JudgmentAChecked}}"></radio> <view class="option-text">A、{{list[indexFlag].OptionA}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionB != }}"> <radio bindtap="changeFlag" data-selectValue="b" checked="{{JudgmentBChecked}}"></radio> <view class="option-text">B、{{list[indexFlag].OptionB}}</view> </view> </radio-group> <checkbox-group wx:elif="{{list[indexFlag].ExamType!= && list[indexFlag].ExamType == 多选}}"> <view class="view" wx:if="{{list[indexFlag].OptionA != }}"> <checkbox bindtap="changeFlag" data-selectValue="a" checked="{{CheckboxAChecked}}"></checkbox> <view class="option-text">A、{{list[indexFlag].OptionA}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionB != }}"> <checkbox bindtap="changeFlag" data-selectValue="b" checked="{{CheckboxBChecked}}"></checkbox> <view class="option-text">B、{{list[indexFlag].OptionB}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionC != }}"> <checkbox bindtap="changeFlag" data-selectValue="c" checked="{{CheckboxCChecked}}"></checkbox> <view class="option-text">C、{{list[indexFlag].OptionC}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionD != }}"> <checkbox bindtap="changeFlag" data-selectValue="d" checked="{{CheckboxDChecked}}"></checkbox> <view class="option-text">D、{{list[indexFlag].OptionD}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionE != }}"> <checkbox bindtap="changeFlag" data-selectValue="e" checked="{{CheckboxEChecked}}"></checkbox> <view class="option-text">E、{{list[indexFlag].OptionE}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionF != }}"> <checkbox bindtap="changeFlag" data-selectValue="f" checked="{{CheckboxFChecked}}"></checkbox> <view class="option-text">F、{{list[indexFlag].OptionF}}</view> </view> <view class="view" wx:if="{{list[indexFlag].OptionG != }}"> <checkbox bindtap="changeFlag" data-selectValue="g" checked="{{CheckboxGChecked}}"></checkbox> <view class="option-text">G、{{list[indexFlag].OptionG}}</view> </view> </checkbox-group> <view wx:elif="{{list[indexFlag].ExamType!= && list[indexFlag].ExamType == 简答题}}"> <view class="textarea"><textarea placeholder="填写答案" bindinput="textChange" maxlength="2000" value="{{textValue}}"></textarea></view> </view> <view wx:elif="{{list[indexFlag].ExamType!= && list[indexFlag].ExamType == 必答题}}"> <view class="textarea"><textarea placeholder="填写答案" bindinput="textChange" maxlength="2000" value="{{textValue}}"></textarea></view> </view> <view wx:elif="{{list[indexFlag].ExamType!= && list[indexFlag].ExamType == 填空题}}"> <view class="textarea" wx:if="{{list[indexFlag].OptionA!=}}"><input placeholder="填写答案" bindinput="textChange" data-inputOption="a" value="{{FillBlankOpationA}}"></input></view> <view class="textarea" wx:if="{{list[indexFlag].OptionB!=}}"><input placeholder="填写答案" bindinput="textChange" data-inputOption="b" value="{{FillBlankOpationB}}"></input></view> <view class="textarea" wx:if="{{list[indexFlag].OptionC!=}}"><input placeholder="填写答案" bindinput="textChange" data-inputOption="c" value="{{FillBlankOpationC}}"></input></view> <view class="textarea" wx:if="{{list[indexFlag].OptionD!=}}"><input placeholder="填写答案" bindinput="textChange" data-inputOption="d" value="{{FillBlankOpationD}}"></input></view> <view class="textarea" wx:if="{{list[indexFlag].OptionE!=}}"><input placeholder="填写答案" bindinput="textChange" data-inputOption="e" value="{{FillBlankOpationE}}"></input></view> <view class="textarea" wx:if="{{list[indexFlag].OptionF!=}}"><input placeholder="填写答案" bindinput="textChange" data-inputOption="f" value="{{FillBlankOpationF}}"></input></view> <view class="textarea" wx:if="{{list[indexFlag].OptionG!=}}"><input placeholder="填写答案" bindinput="textChange" data-inputOption="g" value="{{FillBlankOpationG}}"></input></view> </view> <view class="btn-box"> <view class="left-btn" bindtap="lastQuestion" wx:if="{{currentNumber > 1}}">上一题</view> <view class="right-btn" bindtap="nextQuestion" hidden="{{currentNumber == allNumber}}">下一题</view> </view> <button class="btn weui-btn" type="default" bindtap="handPaper" wx:if="{{currentNumber == allNumber}}">交卷</button> </view>

三、底部试题导航栏设计

具体代码如下,遍历试题列表渲染题号,同时绑定点击事件。

<view class="number"> <view wx:for="{{list}}" bindtap="JumpToQuestion" wx:key="{{index}}" data-id="{{index}}" class="{{ExamProcess[index].Answer!=?Answered:}} {{indexFlag == index?CurrentAnswered:}}">{{index+1}}</view> </view>

点击事件触发获取对应试题进行页面渲染,具体代码如下

注意,每次点击题号时,会重新设置indexFlag的值,这样前端list[indexFlag]就会取到对应的试题进行加载,

JumpToQuestion: function (e) { let data = e.currentTarget.dataset; this.setData({ indexFlag: data.id, currentNumber: data.id + 1, showPopup: true, ExamProcess:this.data.ExamProcess }); // 设置已答题状态 this.setAnsweredQuestionsState(); },

以上就实现了视频中演示的效果。

下一篇讲一下提交试卷和查看作答结果的逻辑。


1063568276