由于本人从事的是在线英语教育工作,所以会做很多学习交互的功能,在英语学习过程中,跟读这种练习口语的功能肯定属于必须的交互,今天就总结一下实现这个跟读打分的功能,以及涉及的知识点。
功能展示




涉及知识点
- TouchEvent事件 (touchstart, touchend, touchcancel)的理解和使用
- readStatus 状态的处理 (default默认, recording录音中, waitingScore等待打分, scoreComplete打分完毕同default可忽略)
- 对应的处理方法
Touch事件讲解
TouchEvent 是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等。 (from MDN)
-
touchstart 当用户在触摸平面上放置了一个触点时触发。事件的目标 element 将是触点位置上的那个目标 element
-
touchend 当一个触点被用户从触摸平面上移除(当用户将一个手指离开触摸平面)时触发。当触点移出触摸平面的边界时也将触发。例如用户将手指划出屏幕边缘。事件的目标 element 和这个 touchend 事件对应的 touchstart 事件的目标 element 相同,哪怕 touchend 事件触发时,触点已经移出了该 element 。
-
touchmove 当用户在触摸平面上移动触点时触发。事件的目标 element 和这个 touchmove 事件对应的 touchstart 事件的目标 element 相同,哪怕当 touchmove 事件触发时,触点已经移出了该 element 。当触点的半径、旋转角度以及压力大小发生变化时,也将触发此事件。
-
touchcancel 当触点由于某些原因被中断时触发。有几种可能的原因如下(具体的原因根据不同的设备和浏览器有所不同):
- 于某个事件取消了触摸:例如触摸过程被一个模态的弹出框打断。
- 触点离开了文档窗口,而进入了浏览器的界面元素、插件或者其他外部内容区域。
- 当用户产生的触点个数超过了设备支持的个数,从而导致 TouchList 中最早的 Touch 对象被取消。
功能分析和讲解
以上几个API是实现模拟录音功能的重要方法,我们在代码中只需要设置一个Element上绑定这些方法,然后完善具体的功能即可,值得注意的是,由于做移动端开发,在本地开发的时候无法在PC上模拟出每个状态下的效果,所以可以给Element绑上相应的鼠标事件。(此处用到的框架是vue)
<button @touchstart="onStartRecord" @touchend="onStopRecord" @touchmove="onPrevent"
@mousedown="onStartRecord" @mouseup="onStopRecord"></button>
注意:在很多情况下,触摸和鼠标事件都会被发送,所以应在对应的方法里调用$preventDefault()
以保持发送鼠标事件
- onStartRecord开始录音功能的方法,具体实现可看注释
onStartRecord: function (event) {
// 阻止默认事件
if (event) {
event.preventDefault();
event.stopPropagation();
}
// 不是可录音状态下不处理
if (this.readStatus != 'default') {
return;
}
console.log('onStartRecord');
this.readStatus = 'recording';
//定义录音的几个回调函数根据自己的业务处理
let scoreCompleteCallback = function (scoreData) {
}.bind(this);
let stopRecordCallback = function () {
}.bind(this);
let scoreErrorCallback = function (error) {
}.bind(this);
//调用和原生定义好的方法去录音打分
mobile.external.StartRecord({
stopRecordCallback: stopRecordCallback,
scoreCompleteCallback: scoreCompleteCallback,
scoreErrorCallback: scoreErrorCallback
});
}
- onStopRecord 停止录音方法
onStopRecord: function (event) {
if (event) {
event.preventDefault();
event.stopPropagation();
}
if (this.readStatus != 'default') {
return;
}
console.log('onStopRecord');
//调用和原生定义好的方法去停止打分
mobile.external.oralStopRecord(this.recordId);
}
- onPrevent 阻止默认的行为
onPrevent: function (event) {
// 阻止默认事件
if (event) {
event.preventDefault();
event.stopPropagation();
}
}
- 根据status状态来更改样式文案等方法
watch: {
readStatus: function($newStatus){
switch ( $newStatus ) {
//根据case来去做什么样式变更之类,此方法灵活使用
}
}
}
写在最后的总结
其实这个功能实现起来不困难,只要掌握了具体的API可以很快完成交互的逻辑,难点在于具体业务实施时与壳的方法联调,各种回掉函数的处理,以及具体设备上体验的质量,本文只是提供一个思路,如果你在书写逻辑时遇到了什么难点,欢迎评论也许可以帮你解决问题。
Cayley 一个不断努力学习的女程序员