前言
在很多学校会存在供学生查看课表的小程序软件,但是由于不同周的同一个时间会出现不同的课,从而导致会出现堆叠的情况,甚至会出现后面的课程把前面的课程给完全覆盖的情况,从而导致页面十分不美观,而且会致使一些被覆盖的课程没办法看到,这个时候可以采用堆叠的方式,让有重叠的课程出现一个与其他不重叠的课程不一样的样式,点击卡片的时候出现多节课程信息,这样可以使整体页面美观,而且功能效果会更好!
1.思路分析
- 根据从教务系统拿下来的数据先进行分析(此处使用我们爬取的部分数据做参考)
在此处分析两个红框分别是其他课程和主课程,在这里我们只看下一个红框,首先判断是否产生重叠主要的依据是黑框框起来的数据,星期和上课时间决定的,要是星期和上课的时间是一样的,那么就要出现重叠的现象,这个时候就需要我们对数据做出一些处理,让两个数据合并为一个数据并且给它加一个样式来于其他的区分开来。
2.这里可以看到对于星期来说,判断很好进行直接对比两个字符串就可以了,而课程节数会出现问题,因为学校的课程一节课不一定只在第一二节或三四节,有可能会出现一到四节的问题,当重叠的位置是四节课和两个两节课时,四节课的时间是第一节到四节课,而两个两节课时的课刚刚好被四节课的课程完全覆盖,这个时候在判断方面,我们就要做出一些处理了,处理完数据之后再进行比较是最好的。
2.实操代码部分
- 首先拿到数据第一步使用正则表达式将num中的数字部分提取出来,然后使用for循环将数字填充完整(此处将切割函数封装成了函数便于代码的管理与维护)
/** * 切割出节数 9-12节 -> 9,10,11,12 */ getNum(all_table: { num: string }) { var num = all_table.num.split(","); var list = []; for (var j = 0; j < num.length; j++) { var day_num_item = num[j].match(/\d+(\.\d+)?/g)!; if (day_num_item.length == 2) { for (var k = parseInt(day_num_item[0]); k <= parseInt(day_num_item[1]); k++) { list.push(k); }; }; }; return list; },
- 切割完之后的数据课程信息会变成一个数组里面存储着有哪几节课时要上这节课,这个时候就要比较看在同一个星期的前提下也没有课程的节数相同的课程
getNowWeekData(classSchedule: { week: any; all_keshes?: any }, nowWeek: number) { var week = classSchedule.week; var nowWeekData = [{ day: "星期日", item: [] }, { day: "星期一", item: [] }, { day: "星期二", item: [] }, { day: "星期三", item: [] }, { day: "星期四", item: [] }, { day: "星期五", item: [] }, { day: "星期六", item: [] } ] as any; try { for (var i = 0; i < week.length; i++) { // 优先显示本周的 if (week[i].name == nowWeek) { for (var dataIdx = 0; dataIdx < week[i].data.length; dataIdx++) { var idx = nowWeekData.findIndex(function (v: { day: any; }) { return v.day == week[i].data[dataIdx].day; }); for (var itemIdx = 0; itemIdx < week[i].data[dataIdx].item.length; itemIdx++) { week[i].data[dataIdx].item[itemIdx].zindex = 3; week[i].data[dataIdx].item[itemIdx].double = false; nowWeekData[idx].item.push((week[i].data[dataIdx].item[itemIdx]) as never); }; }; }; // 其次显示大于本周的 if (week[i].name > nowWeek) { for (var dataIdx = 0; dataIdx < week[i].data.length; dataIdx++) { var idx = nowWeekData.findIndex(function (v: { day: any; }) { return v.day == week[i].data[dataIdx].day; }) for (var itemIdx = 0; itemIdx < week[i].data[dataIdx].item.length; itemIdx++) { // 根据起始判断是否重叠 var numSIdx = nowWeekData[idx].item.findIndex((v: any) => { var itemNum = week[i].data[dataIdx].item[itemIdx].num; if (v.num[0] == itemNum[0] || v.num[v.num.length - 1] == itemNum[itemNum.length - 1]) { return true; } else { return false; }; }); if (numSIdx == -1) { week[i].data[dataIdx].item[itemIdx].zindex = 2; nowWeekData[idx].item.push((week[i].data[dataIdx].item[itemIdx]) as never); } else if (nowWeekData[idx].item[numSIdx].name != week[i].data[dataIdx].item[itemIdx].name) { nowWeekData[idx].item[numSIdx].double = true; }; // 根据末尾判断是否重叠 var numEIdx = nowWeekData[idx].item.findIndex((v: any) => { var itemNum = week[i].data[dataIdx].item[itemIdx].num; if (v.num[v.num.length - 1] == itemNum[itemNum.length - 1]) { return true; } else { return false; } }); if (numEIdx == -1) { } else if (nowWeekData[idx].item[numEIdx].name != week[i].data[dataIdx].item[itemIdx].name) { nowWeekData[idx].item[numEIdx].double = true; } } } } } } catch { };//防止没有课表缓存报错 return nowWeekData; },
此处将涉及到此功能的函数贴出,各位可只查看判断是否重叠部分的代码,其他部分仅做帮助理解,因为使用到了一些定义的变量
3.在使用了这两个函数之后我们发现如果此课程出现了重叠的情况,那么在此课程的数据内的dobule则会显示为true,若没有则会显示为false,所以接下来我们在页面渲染的时候可以通过double值的判断来它到底有没有重叠的情况出现,如若出现重叠情况,则使用重叠样式的模板,要是没有重叠则使用非重叠样式的模板,实现这种控制的方法也很简单,在wx.for内部循环渲染时准备两套模板,用wx.if与wx.else来控制显示哪一套模板就可以啦!
3.效果图部分
小编这里最后的效果图差不多就是这样了,给重叠部分的位置添加了一个阴影的图层,这样看起来还挺不错的吧!这样重叠课程和非重叠课程就区分开来啦!
4.总结
此处粘贴的为ts的代码片段(ts与js写法差不多,js也可用),这两个片段为封装起来的两个函数,各位在查看的时候最好的是理清楚之间的逻辑哦,然后自己再去写一个这样会记得更加的牢固的,这一部分的代码也不是小编自己写的,小编的算法也还的好好提升呢,不过小编对代码片段进行了模仿,基本可以实现一样的功能了,希望各位也可以试试呀!期待和各位一起成长!