今天要分享的是我最近在開發的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; }); }
這樣就能夠了,騷的不像話,親測有效。緩存
一番長篇大論以後,文章也基本講完了,若是你耐心的看完了,恭喜你,又習得一招騷操做,我會不按期的書寫技術文章,有興趣的能夠關注個人公衆號:鏘哥的覺悟。最新文章,一手沙發。拜拜