简单实现video的QA环节

    xiaoxiao2025-05-25  12

    效果图:

    在指定的某个时间点出现QA环节: 回答错误 或 超过规定的时间未回答,出现如下情况:

    思路

    通过定时器(每隔1s的)判断video.currentTime来决定什么时候出现QA环节;出现QA环节时,暂停播放,清理每隔1s的定时器;定义一个变量clickNum来判断是否答题(clickNum=1),默认为未答题(clickNum=0,有一个5s的一次性定时器),若在5s内答题了,则清理这个一次性定时器。答对 +5分(隐藏QA环节,继续播放视频);答错 或 未答题 -5分。显示当前得分,若得分为0则重新播放当前视频(重新开启每隔1s的定时器),反之,则继续播放视频。

    我遇到的问题

    注:按照以上的思路来实现我发现有一点问题:定时器好像没有清理干净,但是自己目前还没想到解决办法

    在QA环节里明明已经选择了答案,点击了 input [type=’radio’]但是一直没有加上它的checked属性,导致不能判断它是否选中。 解决办法: 直接在点击input [type=’radio’]后,就给此input设置checked属性为true.(注意prop()和attr()的区别) ,具体看下面答题部分的代码。

    在规定时间内已经选择了答案,但是在运行完之前的代码,过一段时间还是会进入未答题部分的代码(进入了一次性定时器setTimeout的内部)。 不懂的时候发现如果我在这个一次性定时器的后面直接清理的掉它就不会发生上述问题,但是又多了个新问题:当我鼠标在5s内没有点击input[type=’radio’]的情况下,不能触发time定时器里的回调函数了。所以这样写还有问题滴。 (同时如果再setTimeout使用后立即clearTimeout,会导致setTimeout内的函数不调用。) 原因: 因为我时通过全局变量clickNum=0来判断是否有答题( 答题了,clickNum=1; 未答题,clickNum=0, )而当我没有点击选择时,代码其实已经运行进入了clickNum=0的区域,里面就是这个一次性定时器,而定时器的运行机制里有一点很重要!!!它会把这个一次性定时器放到任务队列里去,所以当我的其他函数运行完之后,过一段时间就开始执行这个time定时器的回调函数了!,例子如下: 一开始就直接把2个定时器都过了遍,直接按顺序放到了任务队列里面去,等待其他更早执行的代码执行完就开始

    解决办法: 在答题的部分(clickNum=1)内部要清理这个一次性定时器! 3. 定时器好像没有清理干净(此问题未解决)

    关键代码

    //开启定时器(1s的,用来判断是否播放到第3s) timeSeconds = setInterval(judgeQA, 1000); function judgeQA() { if (Math.round($video.get(0).currentTime) === 7) { console.log("现在是第3秒"); //到达指定时间就清理外部的定时器(1s的) console.log("清理定时器"); clearInterval(timeSeconds); //移除checked属性,此后若用attr()设置属性为无效 $(".QA-content>input").removeAttr('checked'); //出现QA界面 $video.trigger("pause"); $play.show(); $pause.hide(); $(".QA-wrap").show(); //有答题 $(".QA-content input").click(function () { clickNum = 1; $(this).prop("checked", true); clearTimeout(time); console.log("回答的 清理定时器"); clearInterval(timeSeconds); if ($("#resultY").is(":checked")) { console.log("回答正确!"); score += 5; console.log("score" + score); hideQA(); } else if ($("#resultN").is(":checked")) { //回答错误 console.log("回答错误!"); $(".QA-question").hide().siblings().show(); score -= 5; console.log("score" + score); score = score < 0 ? 0 : score; $('.current-score').text(score); score === 0 ? $video.get(0).currentTime = 0 : ''; timePlay = setTimeout(hideQA, 1000); } }); //未答题超过5s,则视为回答错误 if (clickNum != 1) { console.log("未答题的 清理定时器"); // clearInterval(timeSeconds); time = setTimeout(function () { console.log("进入没有答题de定时器"); //回答错误 $(".QA-question").hide().siblings().show(); score -= 5; console.log("score" + score); score = score < 0 ? 0 : score; $('.current-score').text(score); score === 0 ? $video.get(0).currentTime = 0 : ''; timePlay = setTimeout(hideQA, 1000); }, 3000); } clearTimeout(timePlay); $(".QA-question").show().siblings().hide(); //移除checked属性,此后若用attr()设置属性为无效 $(".QA-content > input").removeAttr('checked'); } else { //浏览器窗口失去焦点,暂停播放 $(window).blur(function () { console.log('window blur'); $video.trigger("pause"); $play.show(); $pause.hide(); }); } clickNum = 0; } function hideQA() { console.log("进入hideQA!"); $('.QA-wrap').hide(); $video.trigger("play"); $play.hide(); $pause.show(); console.log("hideQA里的 清理定时器"); clearInterval(timeSeconds); timeSeconds = setInterval(judgeQA, 1000); console.log("出第2个定时器"); }

    html

    <!--问答环节--> <div class="QA-wrap none"> <div class="QA-content"> <div class="QA-question"> <p>请问百事可乐和可口可乐是同一个国家生产的吗?(你有5s的答题时间,超出则算作回答错误!)</p> <input type="radio" name="result" class="resultY" id="resultY"> <label for="resultY">正确</label> <input type="radio" name="result" class="resultN" id="resultN"> <label for="resultN">错误</label> </div> <div class="QA-error none"> <p style="color: #e00; font-size: 25px">回答错误!减5积分</p> <p>当前积分 <span class="current-score"></span>,最低为0,需重看视频</p> </div> </div> </div>
    最新回复(0)