微信小程序编写一个试卷demo
最近写项目需要有一个试卷功能,作为初学者一头雾水,网上找了些资料。非常感谢
才华横溢吴道简 大佬写的答题小程序。参考了大佬的文章,自己做了一点点修改。欢迎大佬指点。原文链接: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相关推荐
- tp6 关于微信小程序的一个转账demo
这里我的转账是使用的事务,并没有使用队列 控制器 <?php declare (strict_types = 1);namespace app\week2\controller;use app\ ...
- android商品数量加减,微信小程序实现一个简单的商品数量加减案例
简介 这是一个用微信小程序原生代码实现的数量加减demo,主要是用于商品购物车或者商品详情修改数量使用,很简单哦~~~. 核心js方法说明addCount(增加数量) delCount (减少数量) ...
- 微信小程序的考勤管理Demo,包括前后端及数据库等内容
这是一个微信小程序的考勤管理Demo,包括前后端及数据库等内容.如有错误或建议,欢迎指出. 前端:微信小程序框架 后端:koa框架基于express的新一代框架 文件:url80.ctfile.com ...
- 微信小程序编写新闻阅读列表
微信小程序编写新闻阅读列表 本篇学习主要内容 Swiper 组件(轮播图) App.json 里的关于导航栏.标题的配置. Page 页面与应用程序的生命周期 数据绑定(核心知识) 数据绑定的运算与逻 ...
- 微信小程序引入高德地图Demo 快速上手
文章目录 前言 一.获取高德key 二.引入官方实例 总结 前言 本文参照官方文档进行编写 最后引入官方实例 最终效果 ` 一.获取高德key 注册账号 https://lbs.amap.com/?r ...
- 微信小程序开发一个小型商城(四、商品列表)
上一篇文章,微信小程序开发一个小型商城(三.商品分类设计) 在从上一个界面跳转过来,会看到商品列表这个界面:如下图所示: 页面分析:从上到下:分别是一个已经定义好的自定义组件,下面的综合,销量,也是一 ...
- 3元购买微信小程序解决方案一个月
3元购买微信小程序解决方案一个月 参考文章: (1)3元购买微信小程序解决方案一个月 (2)https://www.cnblogs.com/wqcheng/p/7458808.html 备忘一下.
- 微信小程序开发一个小型商城(八、个人页面)
上一篇文章:微信小程序开发一个小型商城(七.支付页面) 在上方还是使用wx:if进行判断是否有登录的数据,有的话将数据当中的图片和名字渲染到页面当中,不存在的话使用一个登录按钮表示需要用户登录.往下分 ...
- 微信小程序入门教程+案例demo
微信小程序入门教程+案例demo 尊重原创,转载请注明出处:原文查看惊喜更多 http://blog.csdn.net/qq137722697 首先摆在好姿态,--微信小程序开发也就那么回事.你只需要 ...
最新文章
- 计算机程序设计考试题目,计算机程序设计员理论试题(题库)
- Linux-makefile
- Java常用分析工具Jps、Jstat、Jinfo、Jstack以及Jconsole的简单介绍和使用
- spring data redis 使用之 spring boot 2.x
- 用Axis创建的Webservice的集成与发布
- js中双感叹号_JavaScript中双叹号(!!)作用
- Java Formatter out()方法与示例
- pythonflask框架_Flask框架
- httplib java_httplib发布调用错误
- 已走过8年时间!百度这一重要产品正式宣布停止服务
- 注释 向 Java 代码中添加元数据
- cmd 根据计算机名查ip地址_如何查找和更改Mac上的IP地址
- 新科高德发布2009.03版电子眼升级数据升级方法: 
1. 新科2440方案机器内
- 【虚拟机数据恢复】误删除VMware虚拟机vmdk文件的数据恢复案例
- Windows Server 2016 实现跨域、跨林之间的访问
- day20 网络编程
- !!. 与 ?. 的区别
- 2021十个最佳linux发行版介绍
- 使用RestTemplate请求第三方接口出错,没抛出异常?
- Spring+SpringMVC+Jsp实现校园二手交易系统
热门文章
- 令人躁动一时且令人不安的TCP BBR算法
- 程序员后来都干啥去了
- 如何使用SMS向客户传递服务信息?指南在这里!
- Progressive Layered Extraction: A Novel Multi-TaskLearning Model for Personalized Recommendations
- 167. 两数之和 II - 输入有序数组633. 平方数之和
- java数组首尾互换,c语言程序,将一个数组首尾互换后输出
- 【大话云原生】煮饺子与docker、kubernetes之间的关系
- 如何轻量化深度学习模型
- 不安装Office操作Excel文件(.xlsx)
- 数据传输速率:传码速率(波特率)、传信速率(比特率)