移動端輸入框填坑系列(一)

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

一、文字輸入限制問題

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

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

Crayon Syntax Highlighter v_2.7.2_beta
$('#input').on('compositionend', function(e) {
        var len = $(this).val().length;
        if (len > 16) {
            // 提示超過16字
        }
    });
[Format Time: 0.0033 seconds]

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

Crayon Syntax Highlighter v_2.7.2_beta
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字提示
        }
    }
});
[Format Time: 0.0036 seconds]

二、textarea置底展示問題

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

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

那麼如果我們需要將 輸入框固定在屏幕下方,而當鍵盤被喚起同時輸入框固定在鍵盤上方 (如下圖樣式)該如何解決呢?

首先我們來看下ios的表現

可以看出,鍵盤會將頁面頂上去。那麼如果希望可以將輸入框和鍵盤完全貼合,我們可以使用div模擬一個假的輸入框,使用定位將真正的輸入框隱藏掉,當點擊假的輸入框的時候,將真正的輸入框定位到鍵盤上方,並且手動獲取輸入框焦點。

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

Crayon Syntax Highlighter v_2.7.2_beta
$('#fake-input').on($.os.ios?'tap' : 'click', function() {
        initHeight = window.innerHeight;
        $('#input').focus();
    });
[Format Time: 0.0013 seconds]

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

Crayon Syntax Highlighter v_2.7.2_beta
$('#textarea').css('height', 0);
    $('#textarea').css('height', $('#textarea')[0].scrollHeight);
[Format Time: 0.0011 seconds]

未完待續…

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