騰訊 AlloyTeam:移動端輸入框填坑系列(一)

做者:yana@alloyteamjavascript

輸入在移動端是一個很經常使用的功能,那麼輸入框必然是一個很重要的部分。然而,移動端輸入框總會遇到各類各樣的問題,不管是樣式仍是ios和android兩端體驗不一致都是很讓咱們頭疼的問題,那麼如何使移動web的輸入框體驗更貼近原生也成了一個須要咱們多多思考和研究的問題。css

1、文字輸入限制問題

咱們拿最多可輸入16個字爲例。當輸入字數(注意,不是字符長度)超過16字時,會觸發tips提示,而且不能繼續輸入。
辦法一:
textarea可使用maxlength進行輸入字數限制。
可是這個辦法只能單純的限制length,有時並不能真正的結局問題。
辦法二:
在將第二個辦法以前先來說講下面的幾種狀況:
一、非直接的文字輸入
什麼叫作非直接的文字輸入呢?java

Alt text

當輸入漢字時必然會是非直接輸入,須要咱們點選才能正式輸入。
當咱們字數限制爲16個字,須要實時檢查是否到16字。輸入文字時,當有非直接的文字輸入時,監聽keydown事件和input事件都會直接觸發判斷字數邏輯,會截斷咱們正在輸入的文字。
解決辦法:
監聽compositionend(當直接的文字輸入時觸發)這時,當沒選中中文的時候不會進行字數判斷。
``android

$('#input').on('compositionend', function(e) {
        var len = $(this).val().length;
        if (len > 16) {
            // 提示超過16字
        }
    });複製代碼

二、emoji表情的輸入
當輸入emoji的時候,可是,當輸入emoji表情的時候,js中判斷emoji表情的length爲2,所以emoji正常應該最多隻能輸入8個,可是ios端卻把emoji的length算爲1,能夠輸入16個emoji。這樣就致使了兩端的體驗不一樣。所以須要在js中來進行字數限制。
再加上漢字輸入問題,那麼就加入一個標記位,來判斷是不是直接的文字輸入。而後監聽input,限制字數,當超過字數限制的時候,把前16個字截斷顯示出來就ok了。
``ios

var cpLock;
$('#input').on('compositionstart', function(e) {
    cpLock = true;
});
$('#input').on('compositionend', function(e) {
    cpLock = false;
});
$('#input').on('input', function(e) {
    if (!cpLock) {
        if (e.target.value.length - 17 >=0) {
            var txt = $(e.target).val().substring(0, 16);
            $(e.target).val(txt);
            // 超過16字提示
        }
    }
});複製代碼

2、textarea置底展現問題

ios中的輸入體驗永遠伴隨着一個問題,就是當喚起鍵盤後,整個頁面會被鍵盤壓縮,也就是說頁面的高度變小,而且全部的fixed所有變爲了absolute。
android效果:
web




使用fixed定位
可見android中喚起鍵盤是覆蓋在頁面上,不會壓縮頁面
在ios上的效果:
性能




那麼若是咱們須要將輸入框固定在屏幕下方,而當鍵盤被喚起同時輸入框固定在鍵盤上方(以下圖樣式)該如何解決呢?
測試


首先咱們來看下ios的表現
ui


能夠看出,鍵盤會將頁面頂上去。那麼若是但願能夠將輸入框和鍵盤徹底貼合,咱們可使用div模擬一個假的輸入框,使用定位將真正的輸入框隱藏掉,當點擊假的輸入框的時候,將真正的輸入框定位到鍵盤上方,而且手動獲取輸入框焦點。

在實現過程當中須要注意下面幾個問題:
一、真正的輸入框的位置計算
首先記錄無鍵盤時的window.innerHeight,當鍵盤彈出後再獲取當前的window.innerHeight,二者的差值即爲鍵盤的高度,那麼定位真輸入框天然就很容易了
二、在ios下手動獲取焦點不能夠用click事件,須要使用tap事件才能夠手動觸發
``this

$('#fake-input').on($.os.ios?'tap' : 'click', function() {
        initHeight = window.innerHeight;
        $('#input').focus();
    });複製代碼

三、當鍵盤收起的時候咱們須要將真輸入框再次隱藏掉,除了使用失去焦點(blur)方法,還有什麼方法能夠判斷鍵盤是否收起呢?
這裏可使用setInterval監聽,噹噹前window.innerHeight和整屏高度相等的時候判斷爲鍵盤收起。
注意:鍵盤彈起須要一點時間,因此計算當前屏幕高度也須要使用setInterval
四、由於textarea中的文字不能置底顯示,當輸入超過一行textarea須要自動調整高度,所以將scrollHeight賦值給textarea的height。當刪除文字的時候須要height也有變化,所以每次input都先將height置0,而後再賦值。
``

$('#textarea').css('height', 0);
    $('#textarea').css('height', $('#textarea')[0].scrollHeight);複製代碼

未完待續...

相關閱讀
踩坑記:當 JavaScript 趕上 UINT64
移動端tryjs異常捕獲
【騰訊TMQ】從0到1:打造移動端H5性能測試平臺


此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處
原文連接:www.qcloud.com/community/a…
獲取更多騰訊海量技術實踐乾貨,歡迎你們前往騰訊雲技術社區

相關文章
相關標籤/搜索