最近写项目需要有一个试卷功能,作为初学者一头雾水,网上找了些资料。非常感谢

才华横溢吴道简 大佬写的答题小程序。参考了大佬的文章,自己做了一点点修改。欢迎大佬指点。原文链接:http://t.csdn.cn/15v4L

首先新建一个文件夹 exam,之后添加数据,假设后台传过来的数据是这样的

Page({data: {answer:{total:5, //总共题目数量subject:[    //数组用来存放所有的题目{title:'题目一',options:[{number:'A',describe:'选项A'},{number:'B',describe:'选项B'},{number:'C',describe:'选项C'},{number:'D',describe:'选项D'},]}, {title:'题目二',options:[{number:'A',describe:'选项A'},{number:'B',describe:'选项B'},{number:'C',describe:'选项C'},{number:'D',describe:'选项D'},]}, {title:'题目三',options:[{number:'A',describe:'选项A'},{number:'B',describe:'选项B'},{number:'C',describe:'选项C'},{number:'D',describe:'选项D'},]},]    }},onLoad(options) {},
})

之后我们需要在页面上渲染,再添加上一题下一题按钮进行题目切换。题目的切换需要添加一个变量,用于记录当前是第几页。通过点击按钮改变index的值,来改变数组subject的下标。

按钮里面通过index的值来控制按钮的显示第一题时,上一题按钮无法点击,最后一页显示交卷按钮。

data里面新增数据

 index:0, //用于记录当前是第几页

.wxml页面

<view ><view>{{answer.subject[index].title}}</view><view class="options"><view>{{answer.subject[index].options[0].number}}</view><view>{{answer.subject[index].options[0].describe}}</view></view><view><view>{{answer.subject[index].options[1].number}}</view><view> {{answer.subject[index].options[1].describe}}</view></view><view><view> {{answer.subject[index].options[2].number}} </view><view>{{answer.subject[index].options[2].describe}} </view></view><view><view> {{answer.subject[index].options[3].number}} </view><view> {{answer.subject[index].options[3].describe}} </view></view>
</view>
<view><button bindtap="last" wx:if='{{index == 0}}' disabled="false">上一题</button><button bindtap="last" wx:else>上一题</button>
</view>
<view><button wx:if="{{index==answer.subject.length-1}}" class="top-sure">交卷</button><button bindtap="next" wx:else>下一题</button>
</view>

两个按钮的点击事件

 next(){          //上一题if(this.data.index<this.data.answer.subject.length-1){this.setData({index:this.data.index+1})}},last(){       //下一题if(this.data.index>0){this.setData({index:this.data.index-1})}}

当前页面显示效果,按钮可以实现题目切换

交卷按钮的点击事件,会有弹窗提示,把答案发送过去之后会跳转页面。

ok: function () {          //提交试卷wx.showModal({title: '提示',content: '确定要提交试卷吗?',success: function (res) {if (res.confirm) {console.log('用户点击确定')// request.sendAnser(this,optionsid,function(res){// wx.reLaunch({// })wx.hideLoading()//)}} else {console.log('用户点击取消')}}})},

接下里需要做的就是选项的点击效果。点击之后选项颜色改变,页面保留被选择的选项。需要一个数组记录每一页被点击的选项。给每一个选项绑定一个不同的id。style="background-color: {{bcA}};"这里通过变量控制选项显示效果。 bindtap="btnOpClick"绑定点击事件。

大概就是这样,放在选项的外层view里面。

 <view class="options" id="0" bindtap="btnOpClick" style="background-color: {{bcA}};" data-options="{{options[0]}}"><view >{{answer.subject[index].options[0].number}}</view><view>{{answer.subject[index].options[0].describe}}</view></view>

data里面的数据

 optionsid:[],//用于记录每一页的选项bc_right: '#98FB98',   //控制选项的颜色bcA: null,bcB: null,bcC: null,bcD: null,

选项点击事件,当一个选项被选中后其余选项颜色为null。这里我定义了一个函数用来改变选项的颜色。因为这个功能需要多次使用,所以这里把他单独写成一个函数。

btnOpClick: function(e){        //点击选项var select=parseInt(e.currentTarget.id )  //通过e.currentTarget.id获取到选项的idthis.change(select)},change(e){          //控制选项的点击效果var index=this.data.indexif (e == 0) {this.setData({ bcA: this.data.bc_right ,bcB: null,bcC: null,bcD: null,});this.data.optionsid[index] = 0}else if (e == 1) {this.setData({ bcB: this.data.bc_right ,bcA: null,bcC: null,bcD: null,});this.data.optionsid[index] = 1}else if (e == 2) {this.setData({ bcC: this.data.bc_right ,bcA: null,bcB: null,bcD: null,});this.data.optionsid[index] = 2}else if (e == 3) {this.setData({ bcD: this.data.bc_right ,bcA: null,bcB: null,bcC: null,});this.data.optionsid[index] =3}},

之后这里会有个问题,当一个选项被选中之后,其余题目的选项也相当于被选中,这里需要在上一题下一题的点击事件中给所有选项的颜色变量赋null,并通过optionsid这一数组记录的数据实现选项颜色的变化。

next(){          //上一题if(this.data.index<this.data.answer.subject.length-1){this.setData({index:this.data.index+1,bcA: null,bcB: null,bcC: null,bcD: null,})this.change(this.data.optionsid[this.data.index])}},last(){       //下一题if(this.data.index>0){this.setData({index:this.data.index-1,bcA: null,bcB: null,bcC: null,bcD: null,})this.change(this.data.optionsid[this.data.index])}}

还有一点就是微信小程序里面想要修改button的样式需要在button标签里面进行修改。

之后我们还可以加一个倒计时,时间结束自动提交试卷,这里需要后台给我们一个数据。倒计时功能这里用到延时函数。这里可能有些绕,首先定义一个setTimeout函数。之后在这个函数里面写一个延时函数setTimeout,延时函数里面再调用setTimeout。延时函数设置的是一秒之后执行。这样通过不断的调用自己,每秒钟执行一次。

setTimeout(){        //时间倒计时setTimeout(()=>{this.setTimeout();}, 1000)},

之后我假定了一个数据timeLong用来表示考试时长。parseInt()用来获取整数,else里面的this。admit()方法是时间到了之后自动提交答案。

 setTimeout(){        //时间倒计时setTimeout(()=>{if(this.data.answer.timeLong>=0){var time=this.data.answer.timeLongvar hour=parseInt(time/3600);var min=parseInt((time%3600)/60)var sec=(time%3600)%60this.data.answer.timeLong=this.data.answer.timeLong-1   //每执行一次时间减一if(hour<1){this.setData({time:min+':'+sec,})if(min<1){this.setData({time:''+sec,})}}else{this.setData({time:hour+':'+min+':'+sec,})}this.setTimeout();}else{this.admit()}}, 1000)},

自动提交答案,wx.showLoading这是微信小程序提供的弹窗方法。这个时候可以在发送请求成功之后调用wx.hideLoading()来隐藏弹窗。我这里是在外部写了一个封装好了发送请求的方法,然后导入进来直接调用的。

admit(){          //考试结束自动提交试卷wx.showLoading({title: '提交中...',icon: 'loading',})// request.sendAnser(this,optionsid,function(res){// wx.reLaunch({//  // })wx.hideLoading()//)}},

动态修改标题,在页面加载时就显示,需要在onLoad函数中进行调用。之后在上一题下一题点击事件中,也要调用这个函数,将index的值传入进来。

setTitle:function(id){   //动态修改标题var length=this.data.answer.subject.length;  //获取总共的题目数量var id=id+1;              let a=id+'/'+lengthwx.setNavigationBarTitle({title: a})},

接下来我把全部的代码附上

js文件的

Page({data: {index:0, //用于记录当前是第几页optionsid:[],//用于记录每一页的选项time:null,bc_right: '#98FB98',   //控制选项的颜色bcA: null,bcB: null,bcC: null,bcD: null,answer:{timeLong:18000, //考试subject:[    //数组用来存放所有的题目{title:'题目一',options:[{number:'A',describe:'选项A'},{number:'B',describe:'选项B'},{number:'C',describe:'选项C'},{number:'D',describe:'选项D'},]}, {title:'题目二',options:[{number:'A',describe:'选项A'},{number:'B',describe:'选项B'},{number:'C',describe:'选项C'},{number:'D',describe:'选项D'},]}, {title:'题目三',options:[{number:'A',describe:'选项A'},{number:'B',describe:'选项B'},{number:'C',describe:'选项C'},{number:'D',describe:'选项D'},]},]    }},onLoad(options) {this.setTitle(this.data.index)this.setTimeout()},btnOpClick: function(e){        //点击选项var select=parseInt(e.currentTarget.id )this.change(select)},change(e){          //控制选项的点击效果var index=this.data.indexif (e == 0) {this.setData({ bcA: this.data.bc_right ,bcB: null,bcC: null,bcD: null,});this.data.optionsid[index] = 0}else if (e == 1) {this.setData({ bcB: this.data.bc_right ,bcA: null,bcC: null,bcD: null,});this.data.optionsid[index] = 1}else if (e == 2) {this.setData({ bcC: this.data.bc_right ,bcA: null,bcB: null,bcD: null,});this.data.optionsid[index] = 2}else if (e == 3) {this.setData({ bcD: this.data.bc_right ,bcA: null,bcB: null,bcC: null,});this.data.optionsid[index] =3}},next(){          //上一题if(this.data.index<this.data.answer.subject.length-1){this.setData({index:this.data.index+1,bcA: null,bcB: null,bcC: null,bcD: null,})this.change(this.data.optionsid[this.data.index])this.setTitle(this.data.index)}},last(){       //下一题if(this.data.index>0){this.setData({index:this.data.index-1,bcA: null,bcB: null,bcC: null,bcD: null,})this.change(this.data.optionsid[this.data.index])this.setTitle(this.data.index)}},ok: function () {          //提交试卷wx.showModal({title: '提示',content: '确定要提交试卷吗?',success: function (res) {if (res.confirm) {console.log('用户点击确定')// request.sendAnser(this,optionsid,function(res){// wx.reLaunch({// })wx.hideLoading()//)}} else {console.log('用户点击取消')}}})},setTimeout(){        //时间倒计时setTimeout(()=>{if(this.data.answer.timeLong>=0){var time=this.data.answer.timeLongvar hour=parseInt(time/3600);var min=parseInt((time%3600)/60)var sec=(time%3600)%60this.data.answer.timeLong=this.data.answer.timeLong-1   //每执行一次时间减一if(hour<1){this.setData({time:min+':'+sec,})if(min<1){this.setData({time:''+sec,})}}else{this.setData({time:hour+':'+min+':'+sec,})}this.setTimeout();}else{this.admit()}}, 1000)},admit(){          //考试结束自动提交试卷wx.showLoading({title: '提交中...',icon: 'loading',})// request.sendAnser(this,optionsid,function(res){// wx.reLaunch({//  // })wx.hideLoading()//)}},setTitle:function(id){   //动态修改标题var length=this.data.answer.subject.length;var id=id+1;let a=id+'/'+lengthwx.setNavigationBarTitle({title: a})},})

wxml页面的

<view>{{time}}</view>
<view><view>{{answer.subject[index].title}}</view><view class="options" id="0" bindtap="btnOpClick" style="background-color: {{bcA}};"><view>{{answer.subject[index].options[0].number}}</view><view>{{answer.subject[index].options[0].describe}}</view></view><view class="options" id="1" bindtap="btnOpClick" style="background-color: {{bcB}};"><view>{{answer.subject[index].options[1].number}}</view><view> {{answer.subject[index].options[1].describe}}</view></view><view class="options" id="2" bindtap="btnOpClick" style="background-color: {{bcC}};"><view> {{answer.subject[index].options[2].number}} </view><view>{{answer.subject[index].options[2].describe}} </view></view><view class="options" id="3" bindtap="btnOpClick" style="background-color: {{bcD}};"><view> {{answer.subject[index].options[3].number}} </view><view> {{answer.subject[index].options[3].describe}} </view></view>
</view>
<view><button bindtap="last" wx:if='{{index == 0}}' disabled="false">上一题</button><button bindtap="last" wx:else>上一题</button>
</view>
<view><button wx:if="{{index==answer.subject.length-1}}" class="top-sure"  bindtap="ok">交卷</button><button bindtap="next" wx:else>下一题</button>
</view>

如有疑惑请在评论区留言,欢迎大家来讨论交流。

微信小程序编写一个试卷demo相关推荐

  1. tp6 关于微信小程序的一个转账demo

    这里我的转账是使用的事务,并没有使用队列 控制器 <?php declare (strict_types = 1);namespace app\week2\controller;use app\ ...

  2. android商品数量加减,微信小程序实现一个简单的商品数量加减案例

    简介 这是一个用微信小程序原生代码实现的数量加减demo,主要是用于商品购物车或者商品详情修改数量使用,很简单哦~~~. 核心js方法说明addCount(增加数量) delCount (减少数量) ...

  3. 微信小程序的考勤管理Demo,包括前后端及数据库等内容

    这是一个微信小程序的考勤管理Demo,包括前后端及数据库等内容.如有错误或建议,欢迎指出. 前端:微信小程序框架 后端:koa框架基于express的新一代框架 文件:url80.ctfile.com ...

  4. 微信小程序编写新闻阅读列表

    微信小程序编写新闻阅读列表 本篇学习主要内容 Swiper 组件(轮播图) App.json 里的关于导航栏.标题的配置. Page 页面与应用程序的生命周期 数据绑定(核心知识) 数据绑定的运算与逻 ...

  5. 微信小程序引入高德地图Demo 快速上手

    文章目录 前言 一.获取高德key 二.引入官方实例 总结 前言 本文参照官方文档进行编写 最后引入官方实例 最终效果 ` 一.获取高德key 注册账号 https://lbs.amap.com/?r ...

  6. 微信小程序开发一个小型商城(四、商品列表)

    上一篇文章,微信小程序开发一个小型商城(三.商品分类设计) 在从上一个界面跳转过来,会看到商品列表这个界面:如下图所示: 页面分析:从上到下:分别是一个已经定义好的自定义组件,下面的综合,销量,也是一 ...

  7. 3元购买微信小程序解决方案一个月

    3元购买微信小程序解决方案一个月 参考文章: (1)3元购买微信小程序解决方案一个月 (2)https://www.cnblogs.com/wqcheng/p/7458808.html 备忘一下.

  8. 微信小程序开发一个小型商城(八、个人页面)

    上一篇文章:微信小程序开发一个小型商城(七.支付页面) 在上方还是使用wx:if进行判断是否有登录的数据,有的话将数据当中的图片和名字渲染到页面当中,不存在的话使用一个登录按钮表示需要用户登录.往下分 ...

  9. 微信小程序入门教程+案例demo

    微信小程序入门教程+案例demo 尊重原创,转载请注明出处:原文查看惊喜更多 http://blog.csdn.net/qq137722697 首先摆在好姿态,--微信小程序开发也就那么回事.你只需要 ...

最新文章

  1. 计算机程序设计考试题目,计算机程序设计员理论试题(题库)
  2. Linux-makefile
  3. Java常用分析工具Jps、Jstat、Jinfo、Jstack以及Jconsole的简单介绍和使用
  4. spring data redis 使用之 spring boot 2.x
  5. 用Axis创建的Webservice的集成与发布
  6. js中双感叹号_JavaScript中双叹号(!!)作用
  7. Java Formatter out()方法与示例
  8. pythonflask框架_Flask框架
  9. httplib java_httplib发布调用错误
  10. 已走过8年时间!百度这一重要产品正式宣布停止服务
  11. 注释 向 Java 代码中添加元数据
  12. cmd 根据计算机名查ip地址_如何查找和更改Mac上的IP地址
  13. 新科高德发布2009.03版电子眼升级数据升级方法: 1. 新科2440方案机器内
  14. 【虚拟机数据恢复】误删除VMware虚拟机vmdk文件的数据恢复案例
  15. Windows Server 2016 实现跨域、跨林之间的访问
  16. day20 网络编程
  17. !!. 与 ?. 的区别
  18. 2021十个最佳linux发行版介绍
  19. 使用RestTemplate请求第三方接口出错,没抛出异常?
  20. Spring+SpringMVC+Jsp实现校园二手交易系统

热门文章

  1. 令人躁动一时且令人不安的TCP BBR算法
  2. 程序员后来都干啥去了
  3. 如何使用SMS向客户传递服务信息?指南在这里!
  4. Progressive Layered Extraction: A Novel Multi-TaskLearning Model for Personalized Recommendations
  5. 167. 两数之和 II - 输入有序数组633. 平方数之和
  6. java数组首尾互换,c语言程序,将一个数组首尾互换后输出
  7. 【大话云原生】煮饺子与docker、kubernetes之间的关系
  8. 如何轻量化深度学习模型
  9. 不安装Office操作Excel文件(.xlsx)
  10. 数据传输速率:传码速率(波特率)、传信速率(比特率)