最近编写了一个问卷调查,但是这个问卷调查的逻辑真的是一言难尽,因为要实现点击之后有不同的显示,在加载的时候先是将所有问题与选项加载出来,然后隐藏(设计数据库,将问题和答案村与数据库中),再根据问题来显示某些选项。
有几个比较坑的点:
- 隐藏的div块应该清除状态;
- 不同的div有着不同的问题,对应不同的input类型(单选、多选、文本…);
- 如果往回点,应该正确隐藏其他的问题;
那么最初的版本为,设计好每个点击之后应该显示的问题,这样实在是繁琐,又有别的麻烦,比如某个问题是有两种情况可以进入的,那难道应该还加个字段判断是第几种情况,然后再显示哪条数据的问题吗,这样肯定把难度加大了,不行不行。 还有隐藏问题,将问题状态清空需要写在方法内,那也不能全部隐藏再显示,只能是隐藏该隐藏的,不需要隐藏的不要管。
于是我想到了之前刷题的时候写的自动状态机,欸,这不正好是自动状态机的业务场景吗!只需要将每个问题的不同选项之后出现的问题做成自动机,那问题应该还是蛮简单的,不过自动机应该写为第几个问题,每个问题的答案跳转至哪里,至于隐藏,那就记一个下标,大于该下标的全部隐藏,然后再显示跳转的问题。😄
又说需要连体显示,一直到下一个有分岔路口的问题,好吧,只需要加一加状态就行。
var gotoMap = {
1: ['btn', 'btn', 'wt2,wt3,wt4', 'wt9,wt10', 'wt7,wt8,wt9,wt10', 'wt5', 'wt6,wt8,wt9,wt10', 'wt7,wt8,wt9,wt10', 'wt7,wt8,wt9,wt10', 'wt8,wt9,wt10'],
4: ['wt14,wt15', 'btn'],
5: ['wt7,wt8,wt9,wt10', 'wt7,wt8,wt9,wt10'],
10: ['wt11,wt12,wt13', 'wt12,wt13'],
13: ['btn', 'btn', 'btn', 'btn', 'btn', 'btn', 'btn'],
15: ['wt16', 'btn', 'wt16'],
16: ['btn', 'btn', 'btn', 'btn', 'btn', 'btn', 'btn', 'btn', 'btn', 'btn']
}
var showArray = new Array(17).fill(0);
/**
* ids 有两个字段,第一个为第几号问题,第二个为第几个选项
* 中间用','隔开
*/
function hideOther(ids) {
var idSts = ids.split(',');
if (gotoMap[idSts[0]] == null) {
return;
}
var idArray = gotoMap[idSts[0]][idSts[1] - 1].split(",");
//隐藏
for (var i = idSts[0]; i <= 16; i++) {
hide('wt' + (Number(i) + 1));
showArray[i] = 0;
}
hide('btn');
//判断显示
for (let i = 1; i <= 16; i++) {
var str = 'wt' + i;
if (!idArray.includes(str)) {
showArray[i - 1] = 0;
} else {
showArray[i - 1] = 1;
}
}
if (!idArray.includes('btn')) {
showArray[16] = 0;
} else {
showArray[16] = 1;
}
//显示
for (let i = idSts[0]; i <= 16; i++) {
if (showArray[i - 1] == 1) {
show('wt' + i);
}
}
if (showArray[16] == 1) {
show('btn');
}
}
- 后记: 需求又改为一个一个问题显示了,再添加上一题下一题,只需要一个数组显示最后一个问题,另一个记录选项即可,选择上一题时删除最后一个,然后清空状态,早这样多简单/(ㄒoㄒ)/~~