移動端彈窗輸入密碼的那些事

內容來自富途web開發團隊,只爲記錄學習,原文鏈接https://juejin.im/post/5b8c90f6e51d4538bb478b4d

該從何說起呢?我先理一理,東西有點多,怕把大家帶溝裏。那現在開門見山,先說一下是什麼事吧。如題所說,其實就是在移動端瀏覽器的新股認購頁面裏面讓用戶輸入交易密碼。

不就是輸入交易密碼,心想看着很簡單,做着也簡單。

以下內容均已富途證券的新股認購模塊爲背景。

入坑前

很happy,果然和心裏想的一樣。新股認購上線沒啥問題。視覺稿的輸入交易密碼大概就是下圖的樣子。新股認購的原稿找不到了,就找了一張bug單代替吧。很簡單,只要校驗輸入的交易密碼是否符合校驗邏輯後提交,沒有多餘的操作。這樣的設計其實前端要做的事並沒有多少。
這裏寫圖片描述

舊版WEB輸入交易密碼

嗯,沒錯。今天說的就是我和上面那個不起眼的輸入交易密碼框的故事。
人生處處有驚喜。要是都是這麼簡單,那麼也就沒那麼多事了。

入坑中

上線後沒過多久。由於新股認購業務的發展需要,頁面需要內嵌到App裏面。心想應該也沒問題,畢竟頁面已經做了移動端適配的。
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在軟鍵盤沒有隱藏的情況下,點擊”確認”提交按鈕無效。

這裏寫圖片描述

用戶反饋,點擊提交無效,這無解。。。求拯救
就這樣,我成功入坑了。
上線第一版,總結上面的輸入交易密碼框在移動端存在的問題:

  1. 不能自動拉起軟鍵盤;
  2. 軟鍵盤沒有隱藏時,無法正常提交交易密碼問題;
  3. 點擊輸入交易密碼拉起的不是數字鍵盤;
  4. 密碼輸入錯誤,沒有重試機會,需要用戶重新點擊“立即認購”,彈出密碼框。

挖坑中…

針對上面出現的問題,優先決定處理問題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。
這裏寫圖片描述
剛解決2個問題,又來2個。

只能怪自己太想當然,得好好反省。總結一下,現在存在的問題:

  1. 不能自動拉起軟鍵盤;
  2. android機交易密碼框被軟鍵盤擋住;
  3. 點擊輸入交易密碼拉起的不是數字鍵盤;
  4. 自動提交代碼後,軟鍵盤沒有自動隱藏。

好吧,還是四個問題。

填坑中…

再來排一次問題優先級,還是問題2和問題4需要優先處理。

問題2 android機交易密碼框被軟鍵盤擋住解決辦法

我們都知道,當我們在頁面輸入數據的時候。一般軟鍵盤拉起的時候,都會把對應的輸入框往上移一段。保證輸入框在頁面的可視範圍內。正常情況如下圖左邊圖1,但是有的瀏覽器在彈出軟鍵盤後,會擋住輸入框,如下圖右2。
這裏寫圖片描述

左1正常,右2有問題

解決的方法就是:

.pwd-wrapper{
    position:fixed;//主要是這個
    top: 10px; //這個
    z-index:999;
}

彈窗原本就是fixed,通過設置彈窗的top屬性,把交易密碼彈窗放到頁面的最上面。這樣就避免彈窗被軟鍵盤擋住。
可能你會覺得這樣很不協調,彈窗沒有上下居中。其實只有存在問題的瀏覽器纔會不居中,但比起軟鍵盤擋住了交易密碼框,要好得多了。除此之外,正常的瀏覽器,儘管我上面寫了top:10px看起來好像沒有上下居中對齊,但是結果確實正常的上下居中對齊。
這讓我相信了,一句話,沒問題的怎麼都沒問題;有問題的,沒問題那也是有問題。
好了,問題2就這樣愉快的解決了。

問題4 軟鍵盤沒有自動隱藏

這個應該很好解決。也就是讓輸入框失去焦點就可以了。

$('input[name="txtPassword"]').blur();

是不是這個問題很白吃呀。這麼簡單,那時候爲什麼沒有加,我記得加了呀。

“明明就是隔壁那位在整理成彈窗密碼組件時JavaScript事件沒加對位置嘛。。。。”。>_> ,開玩笑的。

前端黑科技的降臨

通過一頓猛如虎的操作,用戶體驗上升了不少有沒有。筆芯。。。。

可以鬆一口氣了。然後再來慢慢解決上面還剩下的2個問題。

  1. 不能自動拉起軟鍵盤;
  2. 點擊輸入交易密碼拉起的不是數字鍵盤。

想着,要不先優化拉起的不是數字鍵盤的問題吧。

解決輸入交易密碼沒有拉起數字鍵盤問題

如果沒有對input做特殊類型設置的話,一般都會根據用戶的設置選擇的語言來展示軟鍵盤。

Input 設置type=”text” 方案

一直以來都是使用的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”。發現效果並沒有上面使用 的效果好。

測試代碼如下:

<!-- 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客戶呀,難怪輸入法都有特殊待遇。這就尷尬了,我總不能讓客戶去修改系統的默認輸入法吧。

主要還是因爲第三方輸入法有記錄密碼的風險。
不能等,馬上拉着一票人一起討論,呱唧呱唧呱唧呱唧呱唧呱唧呱唧呱唧呱唧!!!!!
通過討論,得以下幾個方案:

  1. 改爲<input type="password">格式,這樣就可以拉起原生輸入法,但是就不一定時數字鍵盤了
    找客戶端同學幫忙看能不能限制輸入法;
  2. 這樣做App裏面正常,但是瀏覽器裏面還是會有問題
  3. 自己實現密碼輸入鍵盤,想挖坑的方案

但是,上面的所有的方案都不好。況且產品,產品老大也不同意啊。怎麼辦呢???

齊心協力上網搜呀,看看哪些網站有拉起軟鍵盤是原生數字鍵盤的, 終於扒到了一個。

代碼很簡單:
這裏寫圖片描述

勞資,看到這行代碼的時候,差點一屁股坐到了地上。什麼!!!還有這種操作,黑科技呀有沒有。反正我是信了。還等什麼,趕緊試一試。

部分代碼如下:

<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"

這種操作一定要拿小本本記下來。

如何自動拉起軟鍵盤

原來的軟鍵盤一直都沒有自動拉起來。交互邏輯是下面這個樣子,用戶必須手動點擊輸入框,纔會拉起軟鍵盤。
這裏寫圖片描述

不能自動拉起軟鍵盤

現在想實現成可以在用戶點擊“立即認購”按鈕之後,可以自動拉起軟鍵盤。如下圖所示。
這裏寫圖片描述

自動拉起軟鍵盤

一般的做法就是在“立即認購”按鈕上添加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()行不通,需要進行深入研究。

利用Input聚焦可以拉起軟鍵盤的特徵

既然,軟鍵盤只有在用戶手動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()聚焦到其他輸入框,並保證軟鍵盤不會收起,並且可以正常對聚焦的輸入框進行輸入。

走一波。。。。

總體上,都是一些輸入框上的操作,知道了原理,其實也挺簡單的。坑都踩了,還等什麼,趕緊去優化你的輸入框吧。
原文地址:https://futu.im/posts/2018-08-27-input-pwd-on-mobile-browser-dialog/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章