前言:移动web开发中,安卓和IOS的input/textarea输入框在调用键盘是有差别的:安卓机键盘覆盖在页面底部;IOS机键盘将整个页面向顶部推。两种实如今真机上都会致使页面出现某些小问题,本篇主要做用是收录这类问题(也欢迎提供各类问题或者更好的解决方案或指出本文错误,共勉),我会持续更新陆续将遇到到或者身边人遇到的总结到这里,方便本身或者用到的人须要的时候翻出来看看。javascript
IOS 6s手机中,获取焦点时,键盘会将整个页面向顶部推,输入完成后键盘收回可是页面仍是停留在键盘拉起的状态,以下图所示:html
//判断是不是安卓仍是ios isAndroid() { let u = navigator.userAgent; let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器 let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 return isAndroid === true; }
//IOS 6s键盘收回 blurAddr() { if (isAndroid()) return; window.scroll(0, 0);//失焦后强制让页面归位 }
缺点:vue
当页面输入内容较多,页面出现滚动条时,前输入完成后页面立马置顶,若是还要继续输入其余内容,须要手动下滑找到输入框再次输入java
改进:android
//IOS 6s键盘收回 blurAddr() { if (isAndroid()) return; setTimeout(() => { var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;//当失去焦点时,获取网页卷去距离 window.scrollTo(0, Math.max(scrollHeight - 1, 0));//强制重置滚动位置 },100); }
获取焦点时,键盘会直接从底部出来覆盖在页面上层,若是你的输入框恰好在页面下方就会被弹出的键盘遮挡,也没法向上滑动使其显示,以下图所示:ios
"页面根节点"设置style样式:web
<section id="root" style="height:100%;overflow:auto;"> html代码布局 ... 这里用textarea举例 input也是一样的 <textarea onfocus="onFocusAddr()"></textarea> </section>
//安卓键盘遮挡输入 onFocusAddr() { if (!isAndroid()) return;//判断是不是安卓机 setTimeout(() => { let div = document.getElementById("root");//获取根节点 div.scrollTop = div.scrollHeight;//滚动条至底(这里没有写的很严谨,须要减去输入框自身高offsetHeight,效果都同样) }, 500);//键盘拉起的延迟时间 }
缺点:移动web开发
很明显,这个方法不通用,须要给DOM节点绑定id,复用麻烦浏览器
改进:app
//安卓键盘遮挡输入 onFocusAddr() { if (!isAndroid()) return;//判断是不是安卓机 window.addEventListener('resize',()=>{ setTimeout(() => { document.activeElement.scrollIntoViewIfNeeded(); //document.activeElement:文档中当前得到焦点的元素。scrollIntoViewIfNeeded():若是元素不在可见区将其滚动到浏览器窗口的可见区域,负责不动,scrollIntoView()的变体。 }, 0);//键盘拉起的延迟时间 }) }
这是原生解决,建议结合本身使用的框架作改进,如:angularJs,vue框架能够封装成指令,使用更方便,如:
vue中:
directive.js:
import tools from '../../common/utils/tools'; function directives(Vue) { //form表单输入键盘和滚动问题的兼容性处理 Vue.directive('compatible', (el, binding) => { el.onfocus = () => { //安卓得到焦点时键盘遮挡输入 if (!tools.isAndroid()) return;//判断是不是安卓机 window.addEventListener('resize', () => { setTimeout(() => { el.scrollIntoViewIfNeeded(); //document.activeElement:文档中当前得到焦点的元素。 //scrollIntoViewIfNeeded():若是元素不在可见区将其滚动到浏览器窗口的可见区域,负责不动,scrollIntoView()的变体。 }, 0);//键盘拉起的延迟时间 }) }; el.onblur = () => { //IOS 6s键盘收回时强制置顶 if (tools.isAndroid()) return; setTimeout(() => { //当失去焦点时,获取网页卷去距离 var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0; //强制重置滚动位置 window.scrollTo(0, Math.max(scrollHeight - 1, 0)); } ,100); }; }); //禁止输入表情 Vue.directive('no-emoji', (el, binding) => { // eslint-disable-next-line no-useless-escape var regStr = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig; if (regStr.test(el.value)) { el.value = (el.value.replace(regStr, '')).trim(); } el.focus(); }); } export default directives;
main.js:
import directive from './directive/directive'; //全局引用 Vue.use(directive);
form.vue:
<input type="text" maxlength="11" placeholder="请输入手机号" v-compatible v-no-emoji v-model="submitInfo.phone" >
ng中:
directive.js:
angular.module("ngDirective", ["service"]) //IOS 6s键盘收回时强制置顶 .directive("toScrollTop", () => { return { controller: ["$scope", "$element", ($scope, $element) => { $element.bind("blur", (event) => { if (comService.isAndroid()) { setTimeout(() => { var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0; window.scrollTo(0, Math.max(scrollHeight - 1, 0)); }, 100); } }); } }; }]) //安卓得到焦点时键盘遮挡输入 .directive("keyboardDiscover", ["comService", (comService) => { return { controller: ["$scope", "$element", ($scope, $element) => { $element.bind("focus", (event) => { if (comService.isAndroid()) { window.addEventListener('resize', () => { setTimeout(() => { $element.scrollIntoViewIfNeeded(); }, 0);//键盘拉起的延迟时间 }); } }); }] }; }]);
app.js:
import directive from './directive/ngDirective.js'; //全局注入 angular.module("app", [ ... "ngDirective" ])
form.html:
<input type="text" placeholder="请输入手机号" to-scroll-top keyboard-discover ng-model="submitInfo.phone" maxlength="11">