歡迎關注富途web開發團隊,php , 前端須要你。缺人從衆php
該從何提及呢?我先理一理,東西有點多,怕把你們帶溝裏。那如今開門見山,先說一下是什麼事吧。如題所說,其實就是在移動端瀏覽器的新股認購頁面裏面讓用戶輸入交易密碼。css
不就是輸入交易密碼,心想看着很簡單,作着也簡單。html
如下內容均已富途證券的新股認購模塊爲背景。前端
很happy,果真和內心想的同樣。新股認購上線沒啥問題。視覺稿的輸入交易密碼大概就是下圖的樣子。新股認購的原稿找不到了,就找了一張bug單代替吧。很簡單,只要校驗輸入的交易密碼是否符合校驗邏輯後提交,沒有多餘的操做。這樣的設計其實前端要作的事並無[多?]少。android
舊版WEB輸入交易密碼ios
嗯,沒錯。今天說的就是我和上面那個不起眼的輸入交易密碼框的故事。git
人生到處有驚喜。要是都是這麼簡單,那麼也就沒那麼多事了。github
上線後沒過多久。因爲新股認購業務的發展須要,頁面須要內嵌到App裏面。心想應該也沒問題,畢竟頁面已經作了移動端適配的。web
N天就這麼過去了。忽然有一天,負責App設計規範的同窗找到了我。說新股認購頁面的輸入交易密碼操做不符合App設計規範,須要進行修改。滿腦子的???那我,當時就說啦,我這是按WEB這邊的設計規範來作的啊。後端
先說說背景:是這樣的,公司App和WEB都各有一套不一樣的設計規範,平時都不會有太多交集。可是一旦一個按WEB規範製做的頁面內嵌到App裏面,那就有問題了呀。由於根據WEB設計規範作出了的頁面,內嵌到了App裏面,就不必定符合App的設計規範。
App 輸入交易密碼設計稿,能夠看到和WEB徹底不同,這是原生App的輸入框
好吧,這個規範設計交集讓我踩到了。那怎麼辦呢,拉前端負責人,WEB設計負責人,App設計負責人,視覺負責人一塊兒討論唄。
吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧吧唧!!
通過你們的討論,最終決定修改WEB這邊的規範,嘗試使用彈窗輸入交易密碼,把WEB這邊的輸入交易密碼改爲和App的規範一致。也就是下面的彈窗輸入交易密碼的樣子。
交易密碼是6位數字組合
新版-01 WEB輸入交易密碼
從上圖能夠看到,點擊「當即認購」按鈕,就會彈出輸入交易密碼的彈窗,而後點擊彈窗進行輸入(軟鍵盤這個版本並無自動拉起)。輸入完成後,按右圖的1,2步驟提交密碼。
部分交易密碼彈窗HTML:
<div class="ui-dialog-body ui-form">
<div class="ui-form-item" ng-class="{'ui-focus':focused}">
<ul class="pwdList ui-form-text">
<li ng-repeat="item in passwordList track by $index" ng-click="inputFocus()">
<span ng-class="{'dot':item}"></span>
</li>
</ul>
</div>
<input type="text" name="txtPassword" ng-trim="false" ng-model="pwdValue" ng-change="updatePassword();" ng-focus="onFocus();" ng-blur="onBlur()" autocomplete="off" autocorrect="off" maxlength="6">
</div>
複製代碼
經過li展現交易密碼輸入的長度
原理就是把一個透明的input
框放在ul
上面,ul
裏面的li
用來展現輸入密碼的長度。
上線沒多久,有用戶反饋不能提交交易密碼。緣由就是,ios在軟鍵盤沒有隱藏的狀況下,點擊"確認"提交按鈕無效。
用戶反饋,點擊提交無效,這無解。。。求拯救
就這樣,我成功入坑了。
上線初版,總結上面的輸入交易密碼框在移動端存在的問題:
針對上面出現的問題,優先決定處理問題2和問題4。由於已經影響了正常業務流程體驗。這樣優化版就開始了。
爲了解決問題2,你們(又是那一波人)討論決定刪除「取消」和「確認」按鈕,改成自動提交(也就是當用戶輸入密碼位數到達6位,即自動發起後端Ajax請求)。這樣就能夠保證不影響業務。對於問題4,提供二次彈窗輸入交易密碼,使得整個業務操做流程更加流暢。
新版-02 點擊「當即認購」,彈出輸入交易密碼框,輸入完後自動提交,提交完發現密碼錯誤提示「重試」
優化後的版本,更加美觀和高效了,最重要的是用戶體驗也爽了。沒有"確認"按鈕的交易密碼彈窗HTML:
<div class="ui-dialog-box passwordBox" ng-class="{'ui-show': isShowPwd}" ng-show="isShowPwd">
<div class="ui-dialog ui-center">
<div class="ui-dialog-header">
<h3 class="ui-dialog-header-title">{{dtitle||'請輸入富途交易密碼'}}</h3>
</div>
<div class="ui-dialog-body ui-form">
<div class="ui-form-item" ng-class="{'ui-focus':focused}">
<ul class="pwdList ui-form-text">
<li ng-repeat="item in passwordList track by $index" ng-click="inputFocus()">
<span ng-class="{'dot':item}"></span>
</li>
</ul>
</div>
<input type="text" name="txtPassword" ng-trim="false" ng-model="pwdValue" ng-change="updatePassword();" ng-focus="onFocus();" ng-blur="onBlur()" autocomplete="off" autocorrect="off" maxlength="6">
</div>
<i class="ui-icon ui-dialog-close icon-close" ng-click="closeClick()"></i>
</div>
</div>
複製代碼
就這樣,填了本身埋下的2個坑。同時,又給本身挖了2個坑。
沒過多久,客服同窗反饋過來講,Android用戶點擊「當即認購」按鈕後,彈出交易密碼框,點擊輸入交易密碼時發現(這個時候,尚未作自動拉起軟鍵盤),軟鍵盤擋住了輸入框。
點擊輸入交易密碼,軟鍵盤擋住了交易密碼框,個人天呀。。。。
第二個問題是測試的時候,發現自動提交交易密碼後,軟鍵盤並無自動隱藏。被測試同窗提了bug。
嗚嗚嗚嗚嗚嗚嗚嗚,bug。移動端咋這麼多破事。
剛解決2個問題,又來2個。
只能怪本身太想固然,得好好檢討。總結一下,如今存在的問題:
好吧,仍是四個問題。
再來排一次問題優先級,仍是問題2和問題4須要優先處理。
咱們都知道,當咱們在頁面輸入數據的時候。通常軟鍵盤拉起的時候,都會把對應的輸入框往上移一段。保證輸入框在頁面的可視範圍內。正常狀況以下圖左邊圖1,可是有的瀏覽器在彈出軟鍵盤後,會擋住輸入框,以下圖右2。
左1正常,右2有問題
解決的方法就是:
.pwd-wrapper{
position:fixed;//主要是這個
top: 10px; //這個
z-index:999;
}
複製代碼
彈窗本來就是fixed
,經過設置彈窗的top
屬性,把交易密碼彈窗放到頁面的最上面。這樣就避免彈窗被軟鍵盤擋住。
可能你會以爲這樣很不協調,彈窗沒有上下居中。其實只有存在問題的瀏覽器纔會不居中,但比起軟鍵盤擋住了交易密碼框,要好得多了。除此以外,正常的瀏覽器,儘管我上面寫了top:10px
看起來好像沒有上下居中對齊,可是結果確實正常的上下居中對齊。
這讓我相信了,一句話,沒問題的怎麼都沒問題;有問題的,沒問題那也是有問題。
好了,問題2就這樣愉快的解決了。
這個應該很好解決。也就是讓輸入框失去焦點就能夠了。
$('input[name="txtPassword"]').blur();
複製代碼
是否是這個問題很白吃呀。這麼簡單,那時候爲何沒有加,我記得加了呀。
「明明就是隔壁那位在整理成彈窗密碼組件時JavaScript事件沒加對位置嘛。。。。」。>_> ,開玩笑的。
經過一頓猛如虎的操做,用戶體驗上升了很多有沒有。筆芯。。。。
能夠鬆一口氣了。而後再來慢慢解決上面還剩下的2個問題。
想着,要不先優化拉起的不是數字鍵盤的問題吧。
若是沒有對input
作特殊類型設置的話,通常都會根據用戶的設置選擇的語言來展現軟鍵盤。
一直以來都是使用的type="text"
的輸入框。因此點擊彈窗拉起的軟鍵盤是能夠輸入中文的,這顯然和交易密碼要求的數字不符合。
默認彈窗輸入部分代碼:
<div class="ui-dialog-body ui-form">
<div class="noticeInfo">{{notice}}</div>
<div class="ui-form-item" ng-class="{'ui-focus':focused}">
<ul class="pwdList ui-form-text">
<li ng-repeat="item in passwordList track by $index" ng-click="inputFocus()">
<span ng-class="{'dot':item}"></span>
</li>
</ul>
</div>
<input type="text" name="txtPassword" ng-trim="false" ng-model="pwdValue" ng-change="updatePassword();" ng-focus="onFocus();" ng-blur="onBlur()" autocomplete="off" autocorrect="off" maxlength="6">
</div>
複製代碼
在type="text"
的基礎上,經過添加pattern="[0-9]*"
,發現ios能夠正常拉起了數字鍵盤,android上也不是中文輸入法。
開心,這個方案能夠接受。
代碼修改以下:
<input type="text" pattern="[0-9]*" name="txtPassword" ng-trim="false" ng-model="pwdValue" ng-change="updatePassword();" ng-focus="onFocus();" ng-blur="onBlur()" autocomplete="off" autocorrect="off" maxlength="6">
複製代碼
只須要作一點小改動,軟鍵盤的展現已經符合了預期。對好比下圖所示。
左圖爲默認type="text" , 右圖爲type="text" pattern="[0-9]*"
嘗試使用type="number"
和type="password"
。發現效果並無上面使用<input type="text" pattern="[0-9]*">
的效果好。
測試代碼以下:
<!-- type = number -->
<input type="number" name="txtPassword" ng-trim="false" ng-model="pwdValue" ng-change="updatePassword();" ng-focus="onFocus();" ng-blur="onBlur()" autocomplete="off" autocorrect="off" maxlength="6">
<!-- type= password -->
<input type="password" name="txtPassword" ng-trim="false" ng-model="pwdValue" ng-change="updatePassword();" ng-focus="onFocus();" ng-blur="onBlur()" autocomplete="off" autocorrect="off" maxlength="6">
複製代碼
能夠看到type="number"
彈出的是數字鍵盤;但不是9宮格的,type="password"
彈出的是字母,就更不用說了,效果通常。
左圖爲默認type="number" , 右圖爲type="password"
最後,通過對比,決定使用<input type="text" pattern="[0-9]*">
格式。起碼ios拉起的是9宮格,android拉起的是數字鍵盤。
就這樣,優化走一波。。。。。。。
正當我喝着橙汁,聽着小曲兒,擼着代碼的時候。產品發來了一張圖。
當用戶設置搜狗爲默認輸入法
什麼?????????拉起的軟鍵盤竟然時搜狗輸入法,這必定是廣告。
大概問了一下來龍去脈,原來是VVIP客戶呀,難怪輸入法都有特殊待遇。這就尷尬了,我總不能讓客戶去修改系統的默認輸入法吧。
主要仍是由於第三方輸入法有記錄密碼的風險。
不能等,立刻拉着一票人一塊兒討論,呱唧呱唧呱唧呱唧呱唧呱唧呱唧呱唧呱唧!!!!!
經過討論,得如下幾個方案:
<input type="password">
格式,這樣就能夠拉起原生輸入法,可是就不必定時數字鍵盤了可是,上面的全部的方案都很差。何況產品,產品老大也不一樣意啊。怎麼辦呢???
齊心合力上網搜呀,看看哪些網站有拉起軟鍵盤是原生數字鍵盤的, 終於扒到了一個。
代碼很簡單:
勞資,看到這行代碼的時候,差點一屁股坐到了地上。什麼!!!還有這種操做,黑科技呀有沒有。反正我是信了。還等什麼,趕忙試一試。
部分代碼以下:
<div class="ui-dialog-body ui-form">
<div class="noticeInfo">{{notice}}</div>
<div class="ui-form-item" ng-class="{'ui-focus':focused}">
<ul class="pwdList ui-form-text">
<li ng-repeat="item in passwordList track by $index" ng-click="inputFocus()">
<span ng-class="{'dot':item}"></span>
</li>
</ul>
</div>
<input type="tel" pattern="[0-9]*" name="txtPassword" ng-trim="false" ng-model="pwdValue" ng-change="updatePassword();" ng-focus="onFocus();" ng-blur="onBlur()" autocomplete="off" autocorrect="off" maxlength="6">
</div>
複製代碼
竟然真的能夠了,有沒有。使用type="tel"
真的能夠作到彈起的是原生的9宮格鍵盤。看來打電話仍是親爹的。
設置輸入框
type="tel"
這種操做必定要拿小本本記下來。
git commit -a '爲了用戶密碼安全,默認拉起原生9宮格鍵盤'
複製代碼
完事。
原來的軟鍵盤一直都沒有自動拉起來。交互邏輯是下面這個樣子,用戶必須手動點擊輸入框,纔會拉起軟鍵盤。
不能自動拉起軟鍵盤
如今想實現成能夠在用戶點擊「當即認購」按鈕以後,能夠自動拉起軟鍵盤。以下圖所示。
自動拉起軟鍵盤
通常的作法就是在「當即認購」按鈕上添加click
事件,一旦"當即認購"按鈕被點擊,就觸發交易密碼框的focus
事件。
嘗試實現:
修改認購按鈕html:
<button type="submit" class="ui-btn" ng-click="submitApply()">當即認購</button>
複製代碼
經過JavaScript事件進行處理。
$scope.submitApply = function(){
//密碼框聚焦
$input.focus();
$scope.focused = true;//設置flag
}
複製代碼
這種方法,在網上也有一大把。雖然pc端能夠正常執行,可是在移動端卻不能正常拉起軟鍵盤。
結論:直接focus()行不通,須要進行深刻研究。
既然,軟鍵盤只有在用戶手動touch
輸入框foucus
的時候纔會彈起。是否是能夠在原有的基礎上,嘗試把「當即認購」按鈕也改爲input
輸入框,同時使用原有按鈕作背景。
案例走一波,修改按鈕結構爲如下格式:
<div class="sub-container">
<button type="submit" class="ui-btn" ng-class="{'ui-btn-loading': !isCanApplyNewStock}" ng-disabled="!render.agreement||!isCanApplyNewStock" ng-click="submitApply()">當即認購</button>
<input type="tel" pattern="[0-9]*" class="trade-pwd" ng-click="submitApply()">
</div>
複製代碼
作法:也就是把一個透明的input
框放在認購按鈕上面,當用戶點擊的時候,實際上是點擊的是input
輸入框。猜測:這個時候,由於點擊的是輸入框,因此軟鍵盤就會拉起來,同時執行上面的submitApply()
函數,能夠把光標聚焦到交易密碼框上。
按鈕結構
經過真機進行測試,發現竟然能夠正常拉起軟鍵盤。猜測成立。
正常拉起數字軟鍵盤
實踐說明,經過一個input
輸入框,拉起軟鍵盤後,能夠經過JavaScript執行focus()
聚焦到其餘輸入框,並保證軟鍵盤不會收起,而且能夠正常對聚焦的輸入框進行輸入。
走一波。。。。
整體上,都是一些輸入框上的操做,知道了原理,其實也挺簡單的。坑都踩了,還等什麼,趕忙去優化你的輸入框吧。
若是有好的建議,歡迎你們留言交流。
做者:Jin