h5机器人对话式交互设计方案(干货)

前言:

今天要分享的是我最近在开发的h5机器人诊断的心路历程,本文主要讲述的是我本身的方案跟思路,以及琢磨的过程(仅供参考,如下内容均以个人产品为例进行讲解),先上效果图。
图片描述
图片描述
图片描述css

第一张图是开始的对话,第二张图是中途的修改,第三张图是最终的诊断结果,大体就是这么个交互过程。前端

从零开始的思路开启

因为以前没有作过相似的东西,因此我跟你们同样,思路比较的林乱,也不知道要开始从哪里着手,可是不要慌,咱们能够慢慢来分析一下。vue

界面结构分析

首先我分析了功能界面,主要包含四种类型动态的内容,
第一:用户的回复(纯文本),
第二:机器人单选对话块。
第三:机器人多选对话块,
第四:诊断结果内容块。
由于机器人对话是个动态的交互过程,因此不能写死流程,用隐藏显示块的方式来构建一个完整的界面。因此须要把动态库有组件化的思惟封装起来。
(这里声明一下,我并无采用当前比较流行vue框架来构建组件,由于老夫的项目是dom操做框架。)
vue的方式是将数据跟view分离,用数据来渲染出总体界面,待会儿会讲解一下,vue的处理方式。我这里用的是
图片描述
这样的方式来生成dom结构体。jquery

接口设计分析

以前原本是准备把流程写在前端,让前端来决定每一个问题问什么内容,后来这个方案很快的就被我推翻了,若是所有的逻辑写在前端,那就太死板了,没有生命力,并且接口也变得没有活性。特别是针对上下文逻辑紧密结合的对话式分析的话,逻辑万万不能存在前端。
因此我推荐的方案是:先后端逻辑分离。
前端只接收服务端的问题,并回答服务端的问题,服务端接收到问题的答案以后,继续提问新的问题。前端全程不理会我以前回答的是什么,如今回答的是什么,只管回答便可。android

界面操做性

做为一个对话诊断,中途修改回答的内容,是个硬需求。
因此我给的设计是最新的问题,直接操做回答,以前的问题,一概是不能随便再去操做,也就是变成disable模式,(disable模式是针对事件跟样式的,事件是代码去拦截,样式是根据disable来展示成不可操做的css
固然点击右边的修改按钮,以后能够容许那一步的问题能够修改,而后下面的问题从新根据最新的回答来提问。
因为我是dom操做框架,因此个人方式是根据当前的问题块是不是最新的机器人对话框,若是是,就认为是当前问题能够操做,若是小于当前问题块的index,则认为是过去回答的问题,则不容许修改。
这里的会有个问题,若是用户要中途修改的时候,这个逻辑明显就不符合要求,不严谨,因此我须要有两个条件来限定这个不容许修改的状态。
两个限定条件:
一:index
二:对话框是否含有'is-disabled'class
(这里来讲说vue的框架能够这么作,他的组件元素是否点击或者选择,都是由他对应的控制参数来决定的,因此不用dom这样的繁琐,参数数据控制便可),因此我我的认为这种方式在操做控制方面是比dom操做要具备必定的优点。ios

回退还原问题

上面已经介绍了正向所须要的考虑流程,能够一步步的走向到最终的诊断结果。
可是你作过h5,特别是移动端的h5的时候,你就知道什么叫回退问题了。
就是你机器人诊断到疾病结果的时候,点击疾病栏目,跳转到疾病的详情界面,而后再后退的时候,你就会发现你的机器人诊断界面有可能会刷新到最开始起点,以前的对话内容都没有了。
我这里简单的归类了一下刷新状况
android版的微信浏览器,chrome浏览器回退会刷新)
ios版的微信浏览器回退不会刷新)。
做为一个复杂的诊断对话,好不容易选完了,一回退说没就没,从头开始,这个估计是人都能难接受。因此咱们要解决它。chrome

回退还原问题解决思路

我先说会刷新的状况,(不要觉得回退不刷新就没有问题了,有彩蛋,仍是要处理一下),
当咱们的浏览器回退会刷新的时候,咱们须要理清楚两个问题,
1.数据从哪里找回来,
2.数据找回来了,以后,组件的事件怎么办,是否是会丢失,这是咱们最须要考虑的问题。
我为了解决这个问题尝试过不少方案,我以前在尝试的时候,一直在想我若是只保留dom结构,那个人事件岂不是就丢失了吗,由于个人组件都是动态的生成dom,并且他们的事件也都是在他们生成dom结构的时候,动态添加上去的,因此我当时以为,光光保留dom结构是不行的,因此我去找了一些能保留dom节点,同时能保留dom自身的事件的方法。
还别说,还真被我找到了一种,就是几乎没什么人用过的
jquery框架的clone()方法,这个方法能够带参数,默认是false,若是clone(false)的话,能够完整的克隆dom结构。可是没有克隆事件。若是clone(true)的话,能够完整的克隆dom结构,同时还能够保留自身的事件,简直牛逼。
$("p").clone(true)。当我觉得这就是个人救星的时候,我却发现了一个更操蛋的事情,
这个clone出来的对象,只能放在变量里面,无法转成字符串,存在本地,或者其余地方。我试了不少次以后,放弃了,无法保存有个卵用。仍是不舍的放弃了。
后面我调整了思路,若是我先把dom的结构保存下来,还原了,事件我是否是能够在其余地方处理。
结果仍是被我想出来了,事件不要动态化添加,就在界面一开始的时候,在最外层的dom节点上给各个可能出现的组件元素on上点击事件。这样我还原了dom结构以后,事件还能够用,完美。
别高兴太早。咱们的组件他的事件的处理范围是不应超过他自己的对话框的范畴,这又怎么办了,有办法!如图
图片描述
看见mainPart了没有,如此的骚操做就能够解决上面的问题。
这样二者结合,就能够实现还原操做。
dom结构能够这么获取
var chatContent = $("#main-chat-box")[0].innerHTML;
而后把这个chatContent,存到localstorage里面。等返回的时候,刷新的时候先去localstorage去找是否有chatContent的数据,若是有就拿它还原对话的内容界面。后端

存缓存的时机

这里的缓存数据要何时存,何时取呢?
我推荐一个方案:就是点击疾病栏目跳详情的时候,要离开当前的界面的时候,存一份到localstorage,回退的时候,再拿出来,还原上去,并记住及时的清理掉localstorage的缓存数据。
彩蛋来了,这样的代码操做致使一个问题,就是那些不刷新的浏览器,存了一份缓存数据,没有机会去删除了,也就是你下次进入这个机器人界面的时候,就会把上次缓存的东西显示出来,是否是很操蛋,别急,俺有办法,让他也变得回退刷新就行了,这个思路不错)。浏览器

让回退不刷新的浏览器,回退也刷新的骚操做

$(function(){
    var isPageHide = false;
    window.addEventListener('pageshow', function () {
        if (isPageHide) {
            window.location.reload();
        }
    });
    window.addEventListener('pagehide', function () {
        isPageHide = true;
    });
}

这样就能够了,骚的不像话,亲测有效。缓存

总结:

一番长篇大论以后,文章也基本讲完了,若是你耐心的看完了,恭喜你,又习得一招骚操做,我会不按期的书写技术文章,有兴趣的能够关注个人公众号:锵哥的觉悟。最新文章,一手沙发。拜拜

相关文章
相关标签/搜索