背景
iOS 微信中打开 H5 页面输入完成后, 键盘收起页面却没有回退, 留下很大的空白, 轻轻滑动又恢复正常.
事故现场
解决
此处以 vue 项目为例.
要解决这个问题核心就是在元素失去焦点的时候, 手动触发一个页面滚动事件. 但对于这种特定版本才出现的 bug, 逐个去添加 blur 事件代价挺大的, 于是想寻求一种 write once, run anywhere 的方法, 这时候用 mixin 就很合适了. 代码如下:
- Vue.mixin({
- mounted() {
- this.iosInputBack()
- },
- methods: {
- iosInputBack() {
- let ua = navigator.userAgent
- if (/MicroMessenger/i.test(ua) && /(iPhone|iPad|iPod|iOS)/i.test(ua)) {
- let inputArr = document.querySelectorAll('input');
- inputArr.forEach(item => {
- if(!item.addMixinBlur) {
- item.addMixinBlur = true
- item.addEventListener('blur', () => {
- document.body.scrollTop = document.body.scrollTop;
- })
- }
- })
- }
- }
- }
- })
思路就是在页面挂载完成后, 找出页面内的 input 元素, 为其绑定 blur 事件. 但在过程中发现一个页面中 mixin 可能会被执行多次, 因为每个自定义组件自身也会触发 mixin, 为了避免同一个 input 被绑定多次, 可以为其添加一个属性标明是否已经绑定用以区分.
scrollTop 拓展
document.body.scrollTop 是兼容微信浏览器的写法, 其他情况用 document.documentElement.scrollTop, 所以平时要操作 scrollTop 时更好的写法为:
- let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
- document.documentElement.scrollTop = document.body.scrollTop = scrollTop;
以上~
来源: http://www.jianshu.com/p/689949f24b2c