修改记录:
- 2019.10.12 发现ios13存在同样问题,增加了想要修复代码
- 2020.3.3 自定义 vue directive
bug如题,图片如下:
有bug的解决方案
在输入框上监听blur事件,事件触发后将body滚动至底部。
functiont scrollTop () {
// ios12有效
window.document.body.scrollTop = window.document.body.scrollHeight;
// ios13有效 2019.10.12增加
window.document.documentElement.scrollTop = window.document.body.scrollHeight;
}
// el是输入框
el.onblur = scrollTop;
新写了两bug
- bug1: 点击“提交留言”按钮,虽然软键盘收起后页面回滚至底部,但是提交事件没有触发
- bug2: 在多个输入框间切换输入,页面滚动凌乱了,页面先滚至底部又滚回至输入框在可是区域
解决新bug1
原因:
- 输入框blur事件发生在其他事件之前
- 事件回调是同步执行
- 页面滚动了,导致页面的point点坐标不在“提交留言”按钮的位置
- 无法触发“提交留言”按钮的点击事件
解决:
// el是输入框
el.onblur = () => {
setTimeout(scrollTop, 0);
};
解决新bug2
原因:
- 切换输入框后,js代码将body滚动至底部,这是同步的。
- 切换输入框后,webview会将新获取焦点输入框滚动至可视区域,这是异步的。
- bug1的解决方案将输入框失去焦点的回调改成异步,没有解决bug2的问题,
问题变成:在多个输入框间切换输入,webview因输入框切换将获取焦点输入框滚动至可视区域,但是js代码异步将页面滚动至底部,有时导致新获取焦点输入框不在可是范围。
解决: 在输入框获取和失去焦点时,clearTimeout
doms.forEach((item) => {
item.onfocus = () => {
// 元素获取焦点时,由webview滚动元素至可是区域
window.inputFocuseTimeout && clearTimeout(window.inputFocuseTimeout);
};
item.onblur = () => {
window.inputFocuseTimeout && clearTimeout(window.inputFocuseTimeout);
window.inputFocuseTimeout = setTimeout(scrollTop, 0);
};
});
vue directive方案
注册全局directive
import Vue from 'vue'
// 移動端blur后跳轉至頁面最下方
Vue.directive('polyfill-input', {
bind: function (el) {
el.onblur = e => {
window.inputFocuseTimeout && clearTimeout(window.inputFocuseTimeout)
window.inputFocuseTimeout = setTimeout(() => {
if (/\(i[^;]+;( U;)? CPU.+Mac OS X/.test(navigator.userAgent)) {
// ios12
window.document.body.scrollTop = window.document.body.scrollHeight
// ios13
window.document.documentElement.scrollTop = window.document.body.scrollHeight
}
}, 0)
}
el.onfocus = e => {
window.inputFocuseTimeout && clearTimeout(window.inputFocuseTimeout)
}
},
unbind: function (el) {
el.onblur = null
el.onfocus = null
}
})
使用范围:input,textarea标签
<input type="text" v-polyfill-input/>
<textarea v-polyfill-input></textarea>
推荐页面结构
长页面使用以上方案出现页面总是被滚动到底部,因为方案解决问题的中心点就是将body滚动至底部,所以推荐以下页面结构。让#app成为可滚动元素。
<html>
<body>
<div id="#app">
...
</div>
</dody>
</html>
<style>
html, body, #app {
width: 100%;
height: 100%;
}
html, body {
overflow: hidden;
}
</style>
结语
菜鸟第一次写东西,很脆弱的。所以有问题请留言问题,我积极修改。没有问题,请留言鼓励。