html onblur ios,移动web端键盘问题、IOS安卓机input/textarea兼容性

前言:移动web开发中,安卓和IOS的input/textarea输入框在调用键盘是有差异的:安卓机键盘覆盖在页面底部;IOS机键盘将整个页面向顶部推。两种实现在真机上都会导致页面出现某些小问题,本篇主要作用是收录这类问题(也欢迎提供各种问题或者更好的解决方案或指出本文错误,共勉),我会持续更新陆续将遇到到或者身边人遇到的总结到这里,方便自己或者用到的人需要的时候翻出来看看。

一、IOS机

(1)问题描述:

IOS 6s手机中,获取焦点时,键盘会将整个页面向顶部推,输入完成后键盘收回但是页面还是停留在键盘拉起的状态,如下图所示:

4800671482af1bb15a52bf412d9f657f.png

(2)解决方案:

0.判断是否是IOS机

//判断是否是安卓还是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;

}

1.当输入完成(输入框失去焦点onblur)时,强制将页面置顶

//IOS 6s键盘收回

blurAddr() {

if (isAndroid()) return;

window.scroll(0, 0);//失焦后强制让页面归位

}

缺点:

当页面输入内容较多,页面出现滚动条时,前输入完成后页面立马置顶,如果还要继续输入其他内容,需要手动下滑找到输入框再次输入

改进:

//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);

}

二、安卓机

(1)问题描述:

获取焦点时,键盘会直接从底部出来覆盖在页面上层,如果你的输入框刚好在页面下方就会被弹出的键盘遮挡,也无法向上滑动使其显示,如下图所示:

c1d1d98a555c6f576280b4bcdd47dd9f.png

6c9a52b69eff74a31c869d4e2e79e306.png

(2)解决思路:

1.使其可以向上滑动显示:

"页面根节点"设置style样式:

html代码布局

...

这里用textarea举例 input也是同样的

2.当输入框获得焦点时,让页面滚动条至最底部:

//安卓键盘遮挡输入

onFocusAddr() {

if (!isAndroid()) return;//判断是否是安卓机

setTimeout(() => {

let div = document.getElementById("root");//获取根节点

div.scrollTop = div.scrollHeight;//滚动条至底(这里没有写的很严谨,需要减去输入框自身高offsetHeight,效果都一样)

}, 500);//键盘拉起的延迟时间

}

缺点:

很明显,这个方法不通用,需要给DOM节点绑定id,复用麻烦

改进:

//安卓键盘遮挡输入

onFocusAddr() {

if (!isAndroid()) return;//判断是否是安卓机

window.addEventListener('resize',()=>{

setTimeout(() => { document.activeElement.scrollIntoViewIfNeeded();

//document.activeElement:文档中当前获得焦点的元素。scrollIntoViewIfNeeded():如果元素不在可见区将其滚动到浏览器窗口的可见区域,负责不动,scrollIntoView()的变体。 }, 0);//键盘拉起的延迟时间

})

}

(3)问题解决,效果如下图:

aa6c5844da91eff4e543a32472f57c26.png

这是原生解决,建议结合自己使用的框架做改进,如: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:

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:

placeholder="请输入手机号"

to-scroll-top

keyboard-discover

ng-model="submitInfo.phone"

maxlength="11">

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值