欢迎关注富途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