h5前端兼容性问题及解决⽅法集合
整理归纳⼀些之前记录的h5兼容性问题以及相应的解决⽅法,⼤多都是移动端的,持续更新…
1、iOS滑动卡慢
ios⾥⽗元素设置overflow:auto或scroll时,⼦元素滚动时没有滚动惯性,⼿指离开屏幕就⽴即停⽌滚动,所以会有⼀种卡和慢的感觉。
⽬前发现ios13及以上系统没有这个问题,但低版本的还会出现,需要解决。
解决⽅法:
css⾥给滚动⽗元素设置:
-webkit-overflow-scrolling: touch;
慎⽤-webkit-overflow-scrolling属性,会有很多坑,例如内部fixed层级失效、绝对定位元素被⽗元素padding覆盖等。
为了避免使⽤这个属性带来的副作⽤,个⼈总结了以下最佳实践:
.index{
height: 100%;
.content{
height: 100%;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
}
(1) 不要直接给顶层盒⼦index使⽤,⽽是给⼦盒⼦content使⽤。
(2) 凡是相对于屏幕⽽固定位置的都使⽤fixed固定定位,不要⽤absolute。
(3) 所有fixed固定定位的盒⼦都不要放在content⾥,应该放index⾥和content平级。
2、多⾏⽂本溢出隐藏时⽂字被遮挡
常见于移动端,⽐如设置两⾏⽂本溢出隐藏显⽰省略号,个别机型会出现第⼆⾏⽂字下⾯部分显⽰不全。
解决⽅法:
在添加溢出隐藏样式的盒⼦外再套⼀层⽗盒⼦,给这个⽗盒⼦设置固定⾼度,使⾼度撑起来。
3、android端⽂字未垂直居中
情况⼀:⽂字偏上
使⽤height等于line-height或者通过设置上下padding使⽂字垂直居中的⽅法在android会有问题,⽂字偏上,个别安卓机型⽐较明显。
这是个历史问题,简单点说就是css设计时就给字体底部预留了⼀定的空间⽤于展⽰特殊字符,所以实际占⽤空间⽐⽂字看起来的⾼度要⾼。
解决⽅法:
给⽂字所在的元素设置flex布局,通过align-items: center属性来控制垂直居中,并添加padding-top: 1px。
这样基本能满⾜需求,必要时可以再适当加⼤padding-top,但是⼀般建议1px够了,因为不是所有机型都有未垂直居中的问题,避免矫枉过正。
情况⼆:⽂字偏下
这种情况要看⼀下在浏览器中⽂字实际占据的⾼度和⽗盒⼦占据的⾼度的差值,这个差值如果是奇数,可能在⼿机就出现⽂字偏下,可能是移动端css解析间距时最低只精确到1px导致。
解决⽅法:
凑个整呗,给⽗盒⼦⾼度加⼀或减⼀,使间距差值凑个偶数,这样⼀分为⼆就是整数,也就居中了。
4、移动端页⾯跳转时窗⼝⾼度变⼩
移动端输⼊法弹窗弹起时,会导致页⾯窗⼝⾼度变⼩,此时如果跳转到了另⼀个html页⾯,会出现另⼀个页⾯刚打开时获取到的窗⼝⾼度是缩⼩后的⾼度。
解决⽅法:
⽅法1:跳转页⾯之前,先通过document.activeElement.blur()隐藏输⼊法键盘,然后延时300毫秒左右再跳转页⾯。
⽅法2:跳转前先通过window.innerHeight获取输⼊法未弹起时的窗⼝⾼度,再通过地址传参的⽅法传递该⾼度值。
5、ios的数字被识别为电话号码,有默认样式
个别ios机型会⾃动把⼀些数字识别为电话号码,添加了默认样式,⽐如⽹站备案号之类的,⽽且通过设置meta标签也⽆法去除。
解决⽅法:
把被识别为号码的内容通过::before或after伪元素来设置。
6、ios底部margin-bottom失效
css⾥的margin不稳定,能不⽤就不⽤,能⽤padding代替就⽤padding,特别是margin-top和margin-bottom还有其他例如上边距吸顶和下边距重叠的问题。
解决⽅法:
设置⼀个空的div撑起margin-bottom设置的⾼度。
7、定位元素被输⼊法顶起
输⼊法弹起时,窗⼝⾼度缩⼩,导致定位在窗⼝底部的定位元素被顶起,可能会遮盖内容元素。
解决⽅法:
⽅法⼀:input获取焦点时,让定位元素隐藏或改为静态定位,失去焦点时再恢复。
⽅法⼆:不使⽤输⼊法键盘,⽽改⽤前端⼿写的模拟键盘。
附(移动端监听输⼊法键盘弹起及收起的通⽤⽅法):
if(isAndroid){
// 安卓输⼊法弹起时页⾯容器⾼度会缩⼩,⽽ios不会,通过监听窗⼝resize事件,判断html元素的⾼度。
const htmlHeight = document.documentElement.offsetHeight
function setKeyboardActive(){
const currentHeight = document.documentElement.offsetHeight
if(currentHeight < htmlHeight){
// 输⼊法弹起
}else{
// 输⼊法收起
}
}
css设置文字垂直居中window.addEventListener('resize', setKeyboardActive,{ passive:true})
}else if(isIos){
// ios在输⼊法收回时焦点元素会失焦,⽽安卓不会,通过监听focusin和focusout,获取聚焦和失焦的冒泡事件
function setKeyboardActiveTrue(){
// 输⼊法弹起
}
function setKeyboardActiveFalse(){
// 输⼊法收起
}
window.addEventListener('focusin', setKeyboardActiveTrue,{ passive:true})
window.addEventListener('focusout', setKeyboardActiveFalse,{ passive:true})
}
8、ios后台运⾏时倒计时不准
ios应⽤后台运⾏时,js的定时器的执⾏频率会降低直⾄暂停执⾏,恢复⾄前台运⾏时就发现倒计时时间与预期不符。
解决⽅法:不通过执⾏循环次数来判断倒计时时间,改⽤时间戳判断。
9、安卓9.0不显⽰图⽚
安卓9.0开始,不⽀持https协议的⽹页内使⽤http协议的图⽚地址。
解决⽅法:
⽅法1:推荐,换⽤https的图⽚地址。
⽅法2:安卓客户端配置android:usesCleartextTraffic=“true”,出于安全考虑,不建议。
10、ie设置flex纵向布局撑不开
ie下设置 display: flex; flex-direction: column; 时,如果⼦元素设置 flex: 1 ⽆法撑开内容,会覆盖顶部。这是因为 flex: 1 在ie下会被解析成flex: 1 1 0,⽽chrome会解析为flex: 1 1 0%
解决⽅法:
不使⽤ flex: 1 这种简写形式,改⽤ flex: 1 1 0%
11、audio标签autoplay⽆法⾃动播放
由于浏览器的安全限制、防噪⾳等,⾳频不允许⾃动播放。
解决⽅法:
浏览器的限制⽆法突破,只能通过⼈为交互来触发,⽐如点击或滑动事件⾥,获取audio标签元素,调⽤play()⽅法开始播放。12、滚动到顶部⽆效
原⽣js的scrollTo⽅法在个别机型存在兼容性问题。
解决⽅法:
改⽤ele.scrollTop = 0 的⽅式,让滚动⽗容器滚动到指定位置。
13、ios固定定位fixed层级不对
ios⾥定位的层级取决于⽗元素的层级,不管是absolute还是fixed,⽽安卓⾥fixed层级是独⽴计算的。
解决⽅法:
给⽗元素也加定位并设置较⼤的z-index值。
(最好是⼀开始就把所有fixed定位元素放在同级dom下。)
14、ios下⽗元素设置overflow: hidden⼦元素仍超出
ios⽗元素设置了border-radius和overflow: hidden,⼦元素设置绝对定位,仍然会超出,导致边框圆⾓⽆效果。
解决⽅法:
⽗元素设置transform: rotate(0deg);
15、ios元素盒⼦下边框不显⽰
ios个别机型,元素设置的下边框被遮挡或未显⽰。
解决⽅法:
给盒⼦⽗元素添加⾼度撑起来。
16、中⽂输⼊法下触发input事件
中⽂输⼊法在输⼊拼⾳但还没显⽰在输⼊框时也会触发输⼊框的input事件,有些场景下会有副作⽤,⽐如输⼊框搜索联想功能,会产⽣不必要的接⼝请求。
解决⽅法:
js原⽣有个api可以监听⾮直接输⼊事件(包括中⽂输⼊),
// (“inputElement”指代输⼊框元素dom对象)
// 开始⾮直接输⼊时触发,在这个事件⾥可以通过改变⼀个flag变量来控制这个阶段不触发你的业务逻辑
“inputElement”.addEventListener('compositionstart',function(){})
// 结束⾮直接输⼊(开始直接输⼊)时触发,这⾥可以改回flag变量,正常触发你的业务逻辑了
“inputElement”.addEventListener('compositionend',function(){})
17、格式化输⼊⼿机号时光标错位问题
在⼀些要输⼊⼿机号的输⼊框需求⾥,有时需要对⼿机号进⾏344划分显⽰,例如:131 **** ****,在边输⼊边⾃动格式化时个别机型可能出现输⼊光标错位问题,导致输⼊的⼿机号也乱了。
解决⽅法:
利⽤原⽣js的setSelectionRange⽅法,
HTMLInputElement.setSelectionRange ⽅法⽤于设定 input 或 textarea元素中当前选中⽂本的起始和结束位置。
// 以vue代码⽰例
<input v-model="phone" @input="setPhone"/>
setPhone(eve){
this.formatPhone(this.phone)
setTimeout(()=>{
var lenth =this.phone.length
eve.target.setSelectionRange(lenth, lenth)
},20)
}
18、ios屏幕外的图⽚不显⽰
⼀般在写页⾯时遇到图⽚不应该直接写个img标签,⽽是在外层套⼀层div⽗盒⼦,⽅便对图⽚做各种控制,⽽如果图⽚需要圆⾓边框之类的需求,在给图⽚⽗盒⼦加代码来实现时在ios端个别机型会遇到屏幕外的图⽚(滑动查看后仍然)不显⽰的问题。
上述以圆⾓边框来说明是因为要设置圆⾓边框就得加overflow:hidden样式,其实这个问题就是图⽚⽗盒⼦的overflow:hidden代码导致的。
解决⽅法:直接给img标签加overflow:hidden等样式来控制,代码⽰例如下:
.imgBox{
width: 100px;
height: 100px;
img{
width: 100%;
height: 100%;
display: block;
border-radius: 6px;
overflow: hidden;
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论