IOS H5页面input长按退格键时光标错乱问题解决

在iOS中,H5页面里的input输入特别长的内容,长按退格键,会有莫名奇妙的内容会选中

上图就明白


快速删除bug

input里内容已经删除完了,但是莫名其面选中了placeholder,如果没有placeholder,还会选中空白区域

关键这个bug出现的概率还挺高

我开始的解决方法是 在删除文字以后 对input进行一些操作 比如模拟click 让它失去焦点 获取焦点等等

不但不起作用,bug还更严重了。。。


更严重的bug

出现了两个莫名其妙被选中的区域

然后我找了找大厂的页面,也都有这个bug,唯有淘宝没有问题

然后就开始看淘宝的代码,也没什么收获,但是突然想到一个办法

阻止键盘的默认事件

就是按下退格键的时候阻止默认事件,然后自己手动去操作input里面的字符串

相当于自己手动实现了删除文字的功能

直接上代码吧

因为我们是vue的项目,所以我使用vue写的,但是很容易就可以把这个功能抽出来

写了一个directive

```

import Vue from 'vue'

import getDeviceInfo from '../common/deviceInfo'

Vue.directive('inputDelete', {

    inserted: function (el, bind) {

        if (getDeviceInfo().isIOS) {

            el.addEventListener('keydown', (e) => {

                if (e.keyCode === 8) {

                    e.preventDefault()

                    let text = el.value

                    if (text.length) {

                        const start = el.selectionStart

                        const end = el.selectionEnd

                        const length = text.length

                        if (end === length) {

                            if (start !== end) {

                                text = text.slice(0, start)

                            } else {

                                text = text.slice(0, start - 1)

                            }

                        } else {

                            if (end === 0) {

                                return

                            }

                            let p1

                            let p2

                            if (start !== end) {

                                if (start === 0) {

                                    text = text.slice(end)

                                    Vue.prototype.$nextTick(() => {

                                        el.setSelectionRange(0, 0)

                                    })

                                } else {

                                    p1 = text.slice(0, start)

                                    p2 = text.slice(end)

                                    text = p1 + p2

                                    Vue.prototype.$nextTick(() => {

                                        el.setSelectionRange(start, start)

                                    })

                                }

                            } else {

                                p1 = text.slice(0, start - 1)

                                p2 = text.slice(end)

                                text = p1 + p2

                                Vue.prototype.$nextTick(() => {

                                    el.setSelectionRange(start - 1, start - 1)

                                })

                            }

                        }

                    }

                    el.value = text

                    bind.value.target[bind.value.name] = text

                }

            })

        }

    }

})

```

使用方式如下

```

<template>

  <div class="input-delete">

    <input type="text" v-model="text" v-inputDelete="{target: this,name:'text'}">

  </div>

</template>

<script>

export default {

  data() {

    return {

      text: ''

    }

  }

}

</script>

<style>

</style>

```

实现步骤如下

1.阻止默认的删除事件

2.获取光标的位置或者光标所选中的范围,以确定要去掉的字符是哪些

3.分割字符串,把要留下的字符取出来,拼接在一起

4.根据之前光标的位置重新设置光标的位置(这里如果不设置光标的位置,光标就会自动跳到最后)

5.更改input里的值

6.因为是在vue里,只修改input的值是不行的,还要更改data里的值,所以在指令里传了参数过来

问题暂时这样解决了,目前通过测试了

经过简单更改可以用到textarea上等,可以简单更改适用于第三方UI框架上

然而

因为屏蔽了默认行为,导致了一些其他bug

然后我又继续找解决办法

最后用一个莫名其妙的方式解决了

```

import Vue from 'vue'

import getDeviceInfo from '../common/deviceInfo'

Vue.directive('inputDelete', {

    inserted: function (el, bind) {

        if (getDeviceInfo().isIOS) {

            el.addEventListener('keydown', (e) => {

                if (e.keyCode === 8) {

                    window.requestAnimationFrame(() => {

                    })

                }

            })

        }

    }

})

```

就是在删除的时候调用了一下requestAnimationFrame,然后什么也没做,就不会触发ios的快速删除了

真是奇葩

使用也更方便了

```

<input type="text" v-model="text" v-inputDelete>

```

完结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容