最近在做一个前端项目时碰到IOS页面滚动时输入框光标错位不跟随这个问题,网上也查阅了很多解决方法。
目前看到比较多出现这种情况的原因是IOS对fixed定位不友好导致。
但是我不使用fixed定位也能重现出这个问题。
我出现输入框光标错位不跟随的情况是这样的:
body高度设为100%,设置一个div高度为100% overflow:auto,然后在这个div里的input在滚动的时候就会出现光标错位不跟随的问题。
也就是说,没有使用body的自然滚动,而是用一个高度100%的容器做滚动就会出现这个问题。
这里就不讨论fixed定位导致光标错位的解决方法了。
如果不是fixed定位导致光标错位的可以继续往下看。
有人说可以在滚动的时候重绘input,方法是给input改变某个不可见样式触发重绘。我实测了一下,效果很不理想。表现形式是滚动的时候,光标一卡一卡地追赶滚动着的输入框。
大致实现代码是这样的
var node = document.activeElement; //当前focus的dom元素
if (node) {
if (node.nodeName == "TEXTAREA" || node.nodeName == 'INPUT') { //如果是input或textarea
if (node.style.textShadow === '') {
node.style.textShadow = 'rgba(0,0,0,0) 0 0 0'; //改变某个不可见样式,触发dom重绘
} else {
node.style.textShadow = '';
}
}
}
还有说法是样式加上-webkit-overflow-scrolling: touch !important;
实测无效。
咨询了一些比较有经验的前端,给我的方案是监听touchmove事件,当用户用手指上下滑动的时候让输入框失去焦点。这里注意一定是touchmove而不是scroll事件,因为假如监听scroll事件,当用户点击输入框呼出键盘时会触发scroll事件,这样又立刻失去焦点会导致用户无法呼出键盘。
大致实现代码是这样的
var obj = document.getElementById("ele");//滚动容器的id
obj.addEventListener("touchmove", showMsg);
function showMsg(ev) {
document.activeElement.blur();
}
如果大家有什么完美的解决方法请分享一些,谢谢了。