js常见兼容问题
Published in:2021-12-21 | category: 前端 兼容

iPhone7 用 for…in 遍历数组失效

问题描述:最初学习使用 js 时,觉得for...in遍历比for循环简洁,后期在用户反馈后发现 iPhone7 不支持用 for…in 遍历数组
解决方式: 改为for循环遍历

移动端点击事件 300 ms 延迟问题

问题描述:移动端 web 网页是有 300ms 延迟的,往往会造成按钮点击延迟甚至是点击失效。
解决方式:

  • fastclick 可以解决在手机上点击事件的 300ms 延迟
  • zepto.js 的 touch 模块,tap 事件也是为了解决在 click 的延迟问题

audio 和 video 在 ios 和 andriod 中自动播放

出于优化用户体验,苹果系统和安卓系统通常都会禁止自动播放和禁止页面加载时使用 JS 触发播放,必须由用户主动点击页面才可以触发播放。通过给页面根元素加 touchstart 的监听事件实现触发播放

1
2
3
$("html").one("touchstart", function () {
audio.play();
});

iOS 上拉边界下拉出现空白

问题描述:手指按住屏幕下拉,屏幕顶部会多出一块白色区域。手指按住屏幕上拉,底部多出一块白色区域。
产生原因:在 iOS 中,手指按住屏幕上下拖动,会触发 touchmove 事件。这个事件触发的对象是整个 webview 容器,容器自然会被拖动,剩下的部分会成空白。
解决方式:

1
2
3
4
5
6
7
8
9
10
11
document.body.addEventListener(
"touchmove",
function (e) {
if (e._isScroller) return;
// 阻止默认事件
e.preventDefault();
},
{
passive: false,
}
);

ios 日期转换 NAN 的问题

将日期字符串的格式符号替换成’/‘

1
"yyyy-MM-dd".replace(/-/g, "/");

软键盘问题

iOS 系统中文输入法输入英文时,字母之间可能会出现一个六分之一空格

解决方式:可以通过正则去掉

1
this.value = this.value.replace(/\u2006/g, "");

IOS 键盘弹起挡住原来的视图

解决方式:

  • 可以通过监听移动端软键盘弹起 Element.scrollIntoViewIfNeeded(Boolean)方法用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。 如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。
  • true,则元素将在其所在滚动区的可视区域中居中对齐。
  • false,则元素将与其所在滚动区的可视区域最近的边缘对齐。 根据可见区域最靠近元素的哪个边缘,元素的顶部将与可见区域的顶部边缘对准,或者元素的底部边缘将与可见区域的底部边缘对准。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
window.addEventListener("resize", function () {
if (
document.activeElement.tagName === "INPUT" ||
document.activeElement.tagName === "TEXTAREA"
) {
window.setTimeout(function () {
if ("scrollIntoView" in document.activeElement) {
document.activeElement.scrollIntoView(false);
} else {
document.activeElement.scrollIntoViewIfNeeded(false);
}
}, 0);
}
});

onkeyUp 和 onKeydown 兼容性问题

IOS 中 input 键盘事件 keyup、keydown、等支持不是很好, 用 input 监听键盘 keyup 事件,在安卓手机浏览器中没有问题,但是在 ios 手机浏览器中用输入法输入之后,并未立刻相应 keyup 事件

IOS12 输入框难以点击获取焦点,弹不出软键盘

定位找到问题是 fastclick.js 对 IOS12 的兼容性,可在 fastclick.js 源码或者 main.js 做以下修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FastClick.prototype.focus = function (targetElement) {
var length;
if (
deviceIsIOS &&
targetElement.setSelectionRange &&
targetElement.type.indexOf("date") !== 0 &&
targetElement.type !== "time" &&
targetElement.type !== "month"
) {
length = targetElement.value.length;
targetElement.setSelectionRange(length, length);
targetElement.focus();
} else {
targetElement.focus();
}
};

IOS 键盘收起时页面没用回落,底部会留白

通过监听键盘回落时间滚动到原来的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.addEventListener("focusout", function () {
window.scrollTo(0, 0);
});

//input输入框弹起软键盘的解决方案。
var bfscrolltop = document.body.scrollTop;
$("input")
.focus(function () {
document.body.scrollTop = document.body.scrollHeight;
//console.log(document.body.scrollTop);
})
.blur(function () {
document.body.scrollTop = bfscrolltop;
//console.log(document.body.scrollTop);
});

IOS 下 fixed 失效

问题描述:软键盘唤起后,页面的 fixed 元素将失效,变成了 absolute,所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动了。不仅限于 type=text 的输入框,凡是软键盘(比如时间日期选择、select 选择等等)被唤起,都会遇到同样地问题。 解决方法: 不让页面滚动,而是让主体部分自己滚动,主体部分高度设为 100%,overflow:scroll

1
2
3
4
5
6
<body>
<div class='warper'>
<div class='main'></div>
<div>
<div class="fix-bottom"></div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.warper {
position: absolute;
width: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.fix-bottom {
position: fixed;
bottom: 0;
width: 100%;
}
Prev:
文件处理库
Next:
async_await及其实现