uniapp自定義驗證碼輸入框并隱藏光標(biāo)
一. 前言
先看下使用場景效果圖:
- 點擊輸入框喚起鍵盤,藍框就相當(dāng)于input的光標(biāo),驗證碼輸入錯誤或者不符合格式要求會將字體以及邊框改成紅色提示,持續(xù)1s,然后清空數(shù)據(jù),恢復(fù)原邊框樣式;
- 5位驗證碼輸入完畢,點擊頁面其他位置,隱藏鍵盤;這時如果發(fā)現(xiàn)驗證碼有誤,再次點擊輸入框又喚起鍵盤,也能正常刪除數(shù)字(這里其實做的時候遇到了bug,再次聚焦不能刪除錯誤數(shù)字,下文會講到)。
二. 實現(xiàn)思路
具體實現(xiàn)思路:
- 將input標(biāo)簽相對于父元素做絕對定位,與父元素左邊距設(shè)置為負(fù)的本身寬度即可(position: absolute; top: 0; left:-100%; width: 100%; height: 100%;)。
- 動態(tài)去設(shè)置input的focus屬性。
- input同級使用for循環(huán)去創(chuàng)建5個正方形的view標(biāo)簽。
- 給input同級創(chuàng)建的view標(biāo)簽綁定點擊事件,在點擊事件方法實現(xiàn)中去設(shè)置input的focus屬性為true,即可彈出鍵盤。
- 在鍵盤輸入的時候,即可觸發(fā)input屬性的一系列方法,利用v-model雙向綁定,將input輸入的值賦值給循環(huán)的view方框即可。
- 這樣input也就不在屏幕中,但是又可以觸發(fā)input的事件。
總的來說就是,使用for循環(huán)去創(chuàng)建5個正方形的view標(biāo)簽,然后創(chuàng)建一個input標(biāo)簽,type=tel,最大輸入長度為5(根據(jù)需求來設(shè)置),再將input偽隱藏掉,獲取的值分別放到5個view中展示。
驗證碼失敗后利用v-model雙向綁定,清空輸入的值,增加錯誤提示文字和邊框樣式。
三. 代碼實現(xiàn)
父組件
<uni-popup ref="codeInputPopup" background-color="#fff" :mask-click ="false" type="center"> <CodeInput :codeLength="5" :disabled="codeBtnDisabled" @codeInputClose="codeInputClose" @submitGoodCode="submitGoodCode" /> </uni-popup> <script> export default { data() { return { intviation_code:'', //邀請碼 codeBtnDisabled: false //防止接口請求還未返回數(shù)據(jù),用戶多次點擊 } }, methods: { // 提交邀請碼 async submitGoodCode(intviation_code){ this.codeBtnDisabled = true this.intviation_code = intviation_code const response = await this.$api.post('/ebapi/pink_api/secret_intviation_check', { code: intviation_code }) if(response.code === 200){ this.codeBtnDisabled = false this.$refs.codeInputPopup.close() }else{ this.codeBtnDisabled = false this.$refs.codeInputPopup.close() this.$api.msg(response.msg) } }, codeInputClose(){ this.$refs.codeInputPopup.close() this.codeBtnDisabled = false } } </script>
子組件
<template> <view> <view class="code-popup-top"> <view class="code-title">請輸入商品邀請碼</view> <view class="close-icon" @click="codeInputClose"> <uni-icons type="closeempty" size="30" color="#999999" /> </view> </view> <!-- 錯誤提示 --> <view class="code_errow" v-if="codeColor == '#ff0000'&& !isNum">邀請碼必須{{ codeLength }}位數(shù)</view> <view class="code_errow" v-if="codeColor == '#ff0000'&& isNum ">邀請碼必須是數(shù)字</view> <view class="code_input_con"> <view v-for="(item, index) in codeLength" :key="index" class="code_input_item" :style="(index == intviation_code.length? 'border: 5rpx solid #1195db; width: 88rpx; height: 88rpx; line-height: 80rpx;':'color: ' + codeColor + ';' +'border: 2rpx solid' + codeColor)" @click="focus = true" >{{ intviation_code[index] && intviation_code[index] || '' }}</view> <input class="cinput" type="tel" v-model="intviation_code" :maxlength="codeLength" :focus="focus" :cursor="intviation_code.length" @focus="focus = true " @blur="focus = false" /> </view> <button :class="['submit_code_btn', disabled ? 'btn_disabled' : '']" :disabled="disabled" @click="submitGoodCode" >確定</button> </view> </template> <script> export default { data() { return { codeColor: '#313131', //自定義錯誤碼顏色 intviation_code: '', //用戶輸入的驗證碼 focus: false, // 動態(tài)獲取焦點的值 isNum: false, } }, props: { codeLength: { type: Number, default: 5, }, disabled: { type: Boolean, default: false, }, }, methods: { codeInputClose() { this.intviation_code = '' this.$emit('codeInputClose') }, submitGoodCode() { if (this.intviation_code.length === this.codeLength) { if (Number(this.intviation_code)) { this.$emit('submitGoodCode', this.intviation_code) } else { this.isNum = true this.publicErrorSetting() } } else { this.publicErrorSetting() } }, // 輸入不符合規(guī)范,更改樣式并清空 publicErrorSetting() { this.codeColor = '#ff0000' setTimeout(() => { this.intviation_code = '' this.codeColor = '#313131' this.isNum = false }, 1000) }, }, } </script> <style lang="scss" scoped> .code-popup-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 50upx; .code-title { font-size: 34upx; color: #333; font-weight: bold; position: relative; &::before { content: ''; position: absolute; bottom: 0; width: 40upx; height: 19upx; background: linear-gradient( to right, rgba(57, 181, 74, 1), rgba(57, 181, 74, 0.1) ); } } .close-icon { background: #f2f4f7; border-radius: 50%; display: flex; align-items: center; justify-content: center; } } .code_errow { font-size: 30upx; color: #ff5500; margin-bottom: 20upx; } .submit_code_btn { width: 100%; height: 83upx; line-height: 83upx; border-radius: 7upx; background: #39b54a; color: #fff; font-size: 31upx; text-align: center; margin-top: 45upx; } .btn_disabled { color: rgba(255, 255, 255, 0.5) !important; background-color: rgba(57, 181, 74, 0.4) !important; } .code_input_con { display: flex; justify-content: space-around; position: relative; .code_input_item { margin-left: 10upx; text-align: center; line-height: 88upx; border-radius: 14upx; width: 88upx; height: 88upx; font-size: 60upx; font-weight: bold; color: #333; &:last-child { margin-right: 0; } } /*input隱藏掉*/ .cinput { position: absolute; top: 0; left: -100%; width: 100%; height: 100%; } } </style>
四. 過程中遇到的問題
1)input 的type=‘number’, ios手機正常,光標(biāo)在內(nèi)容最后,但Android手機光標(biāo)有時候在內(nèi)容最前面,導(dǎo)致聚焦內(nèi)容刪不掉。
修改input 的type = 'tel'
,:cursor="intviation_code.length"
, 這樣cursor屬性才生效,并指定focus時光標(biāo)的位置在內(nèi)容最后;
type=‘tel’,也會有個小問題,可以輸入一些字符,但是我們的需求只能是數(shù)字,所以代碼中要做限制。就能解決這個問題了。
這個cursor無效的問題,在h5模式應(yīng)該是type的原因,我試了在type是number或digit時cursor就無效,text、tel、idcard就有效
2)還有另外一種方法
- 設(shè)置input的type=“number”,就不需要設(shè)置光標(biāo)位置了;然后隱藏input文字和光標(biāo),相當(dāng)于間接隱藏了input框;
- 用到了css樣式設(shè)置,
color: transparent; caret-color: transparent;
- 最主要的還是相對于父元素做絕對定位,與父元素左邊距設(shè)置為負(fù)的本身寬度的一半即可(position: absolute; top: 0; left:-100%; width: 200%; height: 100%;)with: 200%為了增大點擊區(qū)域,解決Android機型再次喚起鍵盤不能聚焦,刪不掉錯誤數(shù)字的問題。
<template> <view> <input class="cinput" type="number" v-model="intviation_code" :maxlength="codeLength" :focus="focus" @focus="focus = true " @blur="focus = false" /> </view> </view> </template> <script> export default { data() { return { intviation_code: '', //商品邀請碼 focus: false, } }, methods: {} </script> <style lang="scss" scoped> .cinput { position: absolute; top: 0; left: -100%; width: 200%; height: 100%; color: transparent; //輸入文字顏色透明 caret-color: transparent !important; //改變插入光標(biāo)顏色為透明 } } // 考慮兼容性 // 瀏覽器支持caret-color屬性,優(yōu)先使用caret-color(Chrome/Firefox/Opera);其次使用::first-line方法(Safari);最后忽略(如IE)。 @supports (-webkit-mask: none) and (not (caret-color: transparent)) { .cinput { color: transparent !important; } .cinput::first-line { color: transparent !important; } } </style>
還可參考:
6位驗證碼輸入框、隱藏光標(biāo)、letter-spacing失效、自定義光標(biāo),光標(biāo)動畫
uniapp 手機驗證碼輸入框(隨機數(shù)、倒計時、隱藏手機號碼中間四位)可以直接使用
到此這篇關(guān)于uniapp自定義驗證碼輸入框,隱藏光標(biāo)的文章就介紹到這了,更多相關(guān)uniapp驗證碼輸入框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
firefox瀏覽器下javascript 拖動層效果與原理分析代碼
這篇文章主要給大家介紹了關(guān)于在firefox瀏覽器下如何利用javascript實現(xiàn)拖動層效果,以及其中的原理分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,下面來一起看看吧2007-12-12webuploader分片上傳的實現(xiàn)代碼(前后端分離)
這篇文章主要介紹了webuploader分片上傳的實現(xiàn)代碼(前后端分離),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09JavaScript 變量,數(shù)據(jù)類型基礎(chǔ)實例詳解【變量、字符串、數(shù)組、對象等】
這篇文章主要介紹了JavaScript 變量,數(shù)據(jù)類型基礎(chǔ),結(jié)合實例形式詳細(xì)分析了JavaScript變量聲明、字符串、數(shù)組、對象等基本使用方法與操作注意事項,需要的朋友可以參考下2020-01-01JavaScript實現(xiàn)檢查頁面上的廣告是否被AdBlock屏蔽了的方法
這篇文章主要介紹了JavaScript實現(xiàn)檢查頁面上的廣告是否被AdBlock屏蔽了的方法,其實就是利用JS檢測div的名稱和樣式名稱實現(xiàn),需要的朋友可以參考下2014-11-11