前言
前几天公司让写一个客户数据入录页面(就是个带了logo的表单页面),就直接选择用原生的直接上,原以为也就个把小时的事情(确实个把小时就写完了),但是测试发现ios(没有测试多个,至少qq浏览器会)会输入的时候导致页面上推
严重影响用户体验。
可直接转第三部分
由开源库找到方案
Vant Field组件
通过看源码发现Field
在blur事件时候会执行一个滚动事件
贴代码:reset-scroll.ts
// reset-scroll.ts
import { isIOS as checkIsIOS } from '../validate/system';
import { getRootScrollTop, setRootScrollTop } from './scroll';
const isIOS = checkIsIOS();
/* istanbul ignore next */
export function resetScroll() { // 触发blur事件后会执行该函数
if (isIOS) {
setRootScrollTop(getRootScrollTop());
}
}
贴代码 system.ts
import { isServer } from '..'; // 不是很重要单纯的判断是不是服务器渲染
// ...
// 判断是不是ios 服务器渲染直接不判断
export function isIOS(): boolean {
/* istanbul ignore next */
return isServer
? false
: /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase());
}
贴代码:scroll.ts
// 部分代码
// ...
export function getRootScrollTop(): number {
return (
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop ||
0
);
}
// ...
export function setScrollTop(el: ScrollElement, value: number) {
if ('scrollTop' in el) {
el.scrollTop = value;
} else {
el.scrollTo(el.scrollX, value);
}
}
// ...
export function setRootScrollTop(value: number) {
setScrollTop(window, value);
setScrollTop(document.body, value);
}
// ...
转换成原生代码 or 解决方案
逻辑
- 监听blur
- 判断是否是ios
- 滚动到原来的位置
代码
<style>
input{
/* 模拟输入框位置 */
margin-top:500px;
}
</style>
<input type="text" >
<script>
// 检查是否是ios
function checkIsIOS(){
return /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase())
}
// 设置滚动元素(兼容性问题)
function setRootScrollTop(value) {
setScrollTop(window, value);
setScrollTop(document.body, value);
}
// 设置滚动位置
function setScrollTop(el, value) {
if ('scrollTop' in el) {
el.scrollTop = value;
} else {
el.scrollTo(el.scrollX, value);
}
}
// 获取滚动位置
function getRootScrollTop() {
return (
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop ||
0
);
}
const isIOS = checkIsIOS();
// 执行还原滚动条
function resetScroll() { // 触发blur事件后会执行该函数
if (isIOS) {
// 这是滚动条位置
setRootScrollTop(getRootScrollTop());
}
}
const _input = document.querySelector('input');
// 监听失去事件
_input.onblur = ()=>{
console.log('onblur')
resetScroll();
// TODO: ...其他操作
}
</script>