在iOS中,H5页面里的input输入特别长的内容,长按退格键,会有莫名奇妙的内容会选中
上图就明白
input里内容已经删除完了,但是莫名其面选中了placeholder,如果没有placeholder,还会选中空白区域
关键这个bug出现的概率还挺高
我开始的解决方法是 在删除文字以后 对input进行一些操作 比如模拟click 让它失去焦点 获取焦点等等
不但不起作用,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
}
})
}
}
})
```
使用方式如下
```
export default {
data() {
return {
text: ''
}
}
}
```
实现步骤如下
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的快速删除了
真是奇葩
使用也更方便了
```
```
完结