移动端输入框存在的一些问题

文字输入限制

知识点
  • 直接文字输入

    输入英文、符号等直接显示在输入框中的字符称为直接文字输入

  • 非直接文字输入

    输入中文时是非直接文字输入,只有选中文字之后才算正式输入,非直接文字输入开始及结束时会相应的触发compositionstart, compositionend事件

max-length属性只针对直接文字输入

要求
  1. 输入限制8个字
  2. 实时检查是否达到限制字数,alert提醒
常见的解决方案
  1. 设置input元素的maxlength属性
  2. 监听keydown, input事件

    $('#input').on('input', function(e) {
     console.log('input')
     const len = $(this).val().length
     if (len > 8) {
       alert('input more than 8')
     }
    })
    
存在问题
  • 非直接文字输入

    假如我们要起名字:“思超煎饼”,那么完整输入流为:si’chao’jian’bing,但是上面的实现方案在输入到 si’chao’j 就会触发alert,从而导致用户输入中断,此时输入框内容为 si’chao’j, 用户只能一个字一个字的输入才能成功,用户体验很差。

  • emoji表情输入

    当输入emoji表情时,Android和PC端中 maxlength 判断emoji表情的length为2,因此正常情况下emoji最多4个,但是在iOS端中maxlength对 emoji长度判定为1,导致多端体验不同

解决方案
  1. 为了防止emoji表情的判断问题,不使用maxlength属性,使用js判断长度
  2. 针对非直接文字输入,使用compositionstart, compositionend, input事件监听输入框, 前两个事件判断当前是否为直接文字输入,选中文本之后如果超过字数限制时截取前8个字符
代码
// html
<input id="input"></input>
// js
const setCutTxt = (element, txt, start, end) => {
  element.val(txt.substring(start, end))
}

let compositioning = false
$('#input').on('compositionstart', function(e) {
  compositioning = true
})
$('#input').on('compositionend', function(e) {
  compositioning = false
  if (e.target.value.length > 8) {
    setCutTxt($(e.target), $(e.target).val(), 0, 8)
    window.alert('input more than 8')
  }
})
$('#input').on('input', function(e) {
  if (!compositioning) {
    log(e.target.value.length)
    if (e.target.value.length > 8) {
      setCutTxt($(e.target), $(e.target).val(), 0, 8)
      window.alert('input more than 8')
    }
  }
})

有一点要注意的是:在iOS端搜狗输入法输入中文时不会触发compositionstart和compositionend事件,自带输入法则会触发。

输入框位置问题

知识点

在iOS中,唤起键盘后,页面会被键盘压缩,即页面高度变小,同时,页面中所有position为fixed的元素变为absolute。

要求
  1. 将输入框固定在屏幕下方
  2. 键盘唤起时固定在键盘上方
常见方案
// html
<style>
  input {
    position: fixed;
    left: 0;
    bottom: 0;
  }
</style>

<input id="input"></input>
存在问题

在iOS端,键盘弹起时,fixed失效,变为absolute,所以弹起的键盘会遮住输入框

解决方案
  1. 键盘未唤醒时使用div模拟一个假输入框,使用定位隐藏真的输入框(position: absolute)
  2. 点击div时,聚焦真输入框并将定位到键盘上方
注意事项

真输入框的位置计算

  1. 页面载入时记录此时的 window.innerHeight
  2. 唤醒键盘之后再获取此时的 window.innerHeight, 得到键盘高度
  3. 设置真输入框:left: 0; bottom: 键盘高度;

键盘弹起和收起需要一定的时间

  1. 键盘弹起计算高度的时候要使用setInterval定时监听innerHeight高度
  2. 键盘收起时同样要使用setInterval监听

iOS中获取焦点不能使用click事件,而是tap事件

$('#input').on($.os.ios ? 'tap' : 'click', () => {})
0%