h5兼容性问题
1、移动端input总结
ios13.1 input错位问题
cloud.tencent.com/developer/a…
结论:最简单的方法,input聚焦的时候
window.scrollTop(0)
input 样式字体上下居中问题
设计师给的input样式通常都是外框高,输入的内容区域低,要求输入的内容区域在input上下居中。
比如如下图片:
第一种方法,给input添加个父元素(推荐)
如图,蓝色框为div,红色框为input
第二种方法,针对不同系统改样式
红色框一整个都为input
对于
placeholder
样式,在ios端它的字体不会上下居中,而android会。所以要针对ios做特殊的处理,可以设置line-height
来进行微调,以达到居中效果。也可以设置padding- top
进行微调,但是有可能字体会被遮挡。
经过真机测试,line-height
和padding-top
在::placeholder
的设置只有ios生效。
input::placeholder {
line-height:36px;
/*或者*/
padding-top: 10px;
}
对于input输入文字后,文字的样式同样在ios端它的字体不会上下居中,而android会。可以针对ios设置padding-top
进行微调。注意设置line-height
是无效的
input {
padding-top: 10px;
}
input唤起与隐藏细节总结
1、自动聚焦
点击非input元素,让input元素聚焦的关键是 有点击事件,而且input元素在点击发生前就需要存在于dom树下。故此input可以用visible或者z-index来设置隐藏。
2、弹出系统输入框不遮盖输入框上面的元素
输入框元素与上面不想被遮盖的元素是兄弟节点
,且两个元素的position != fixed || absolute
。
<div class="wrapper">
<div class="zone1"></div>
<input type="text">
<div class="showInput"></div>
</div>
当点击showInput的时候,showInput隐藏,input从z-index=-1 变成z-index=1。
3、通过监听onBlur事件来让输入框隐藏
注意:
1、如果发送按钮是跟输入框一同消失与出现,则onBlur里面设置让input隐藏的代码要延迟300毫秒,再执行。保证发送按钮的事件能够触发。
2、在IOS上
,输入中文拼音后(未选择文字)直接触发input的blur事件,此时输入键盘关闭,当再次唤起输入键盘时,会先触发input的blur事件,再触发focus事件。这里会导致的问题就是1
所设置的延迟300毫秒会触发,表现为输入键盘弹起了,但是你的输入框被你隐藏了。解决的方法当想要唤起输入键盘时,清除1
所设置的延迟函数。
4、自定义input框会概率性隐藏
通过函数触发自定义input组件(position:absolute; bottom: 0)的focus方法来唤起键盘,在ios上如果来回重复关闭与隐藏输入键盘,会概率性出现自定义input组件没有被输入键盘顶上去,而是被藏在输入键盘的后面。
限制输入只能为数字且限制长度
<input
className={cs.inputCode_input}
type="text"
pattern="[0-9]*"
autoComplete="one-time-code"
inputMode="numeric"
maxLength={6}
/>
解决方法是:
自定义input组件的input元素的value必须含有值。
- 当自定义input框隐藏时,给input的value设置为空格。
- 当自定义input框显示时, 如果input的value原本是空格,则清空。
- 当自定义input框触发发送按钮时,将input的value设置为空格。
2、canvas的坑
在移动端ios上,canvas的渲染区域的前面如果有元素,当页面是可以滚动且canvas是在顶部的时候,因为ios的渲染机制会导致canvas在视觉效果上覆盖掉元素。
解决方法:
transform: translateZ(0);//给元素添加,通过硬件加速让元素优先级高于canvas
3、点击div元素有阴影
解决方案
transform: translate3d(0,0,0);
4、ios滚动吸底元素抖动
原因:
如果滚动区域也就是元素设置了overflow-y: scroll;吸底元素是滚动区域的子节点
,则会出现抖动。
解决方法:
滚动区域与吸底元素同为兄弟节点
,或者吸底元素不是滚动区域的的子节点
。
5、vh存在的问题
6、ios下拉刷新
在一些设备上,ios下拉刷新整个页面,出现顶部间距展示异常情况。
解决方法
组件渲染完成后执行一次如下方法
useEffect(() => {
setTimeout(() => {
window.scrollTo({
top: 1,
left: 0,
behavior: 'smooth',
})
}, 100);
}, [])
7、ios图片没有渲染问题
在一些ios设备上,图片通过transfrom使用硬件加速也没有渲染出来,可以改通过动画的方式强制启用。
.wrapper {
position: relative;
width: 100%;
animation: forceRender 0.05s ease 0s;
}
@keyframes forceRender {
0% {
transform: translateX(1px);
}
100% {
transform: translateX(0);
}
}
8、弹框后阻止后面的元素滚动
背景
h5项目在移动端上如果弹窗后,滑动弹窗后,弹窗后面的元素也会滚动。
解决方法1(touchmove)
当弹窗出现的时候,给body设置事件,禁止默认事件的触发,弹窗消失则消除事件。react代码如下:
useEffect(() => {
const handleMove = e => {
e.preventDefault()
}
document.body.addEventListener('touchmove', handleMove, {
passive: false, // 一定要设置passive: false
})
return () => {
document.body.setAttribute('style', style)
document.body.removeEventListener('touchmove', handleMove)
}
}, [])
缺陷:
如果弹窗内容有滚动元素,会导致无法滚动。
解决方法2(overhidden)
当弹窗出现的时候,给body设置style,height = '100vh'、overflow = 'hidden',弹窗消失则恢复原样。react代码如下:
useEffect(() => {
const style = document.body.getAttribute('style') || ''
document.body.style.height = '100vh'
document.body.style.overflow = 'hidden'
return () => {
document.body.setAttribute('style', style)
}
}, [])
缺陷:
ios设备无效。
解决方法3(同级结构fixed)
弹窗元素与弹窗后面的元素在html的结构上是同一层级。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.one {
position: relative;
width: 100vw;
height: 200vh;
background: linear-gradient(blue, pink);
color: white;
}
.two {
position: fixed;
top: 0;
width: 100vw;
height: 100vh;
background-color: black;
overflow-x: scroll;
opacity: 0.5;
}
.three {
position: relative;
height: 200vh;
background: linear-gradient(yellow, green);
}
</style>
</head>
<body>
<div class="one">
可以明显看到,one并没有滚动
</div>
<div class="two">
<div class="three">
</div>
</div>
</body>
<script>
</script>
</html>
css常用设置
1、backgroun-image与img的区别
- backgroun-image不能同时设置宽高与object-fit,img可以。这意味着h5的大背景图(底板)不能用backgroun-image来适配,否则会
变形
。
2、文字描边效果
有两种css属性:
第一种:支持数字与英文
-webkit-text-stroke: 2px #E1FF37;
text-stroke: 2px #E1FF37;
第二种:支持数字、英文与中文
text-shadow: 0 2px #e1ff37, 2px 0 #e1ff37, -2px 0 #e1ff37, 0 -2px #e1ff37;
3、css设置省略号
单行省略号
white-space: nowrap;
max-width: 250px;
overflow: hidden;
text-overflow: ellipsis;
多行省略号
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
word-break: break-all; // 设置文字切断的方式为强制切断
text-overflow: ellipsis;
width: 100px;
4、滚动-禁止页面滚动
-
使用js方法:
-
使用css的pointer-events方法解决
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="scroll">
<div class="scrollContent"></div>
</div>
<div class="dialog"></div>
</body>
</html>
<style>
.scroll {
position: absolute;
width: 100vw;
height: 100vh;
background-color: aqua;
overflow-y: scroll;
overflow-x: hidden;
pointer-events: none;
}
.scrollContent {
position: absolute;
width: 100vw;
height: 200vh;
background:linear-gradient(red,blue);
}
</style>
<script>
export let scrollHandle = {
dom: {
el: null,
style: '',
},
// 给dom元素的style基础上添加pointer-events,停止滚动
stopMove() {
let { el, style } = this.dom;
el.setAttribute('style', style + '; pointer-events: none;');
},
// 初始化返回原来的dom的样式
reset() {
let { el, style } = this.dom;
el.setAttribute('style', style);
},
init(dom){
this.dom.el = dom;
this.dom.style = dom.getAttribute('style') ? dom.getAttribute('style') : '';
}
}
</script>
核心关键是:
overflow-y
与pointer-events
要同时在一个元素上。- 当dialog弹出来的时候,给srcoll设置
pointer-events: none;
- dialog与
pointer-events
元素为兄弟元素,因为pointer-events
会把里面所有的dom事件全部无效后。
5、滚动-移动端隐藏滚动条
*::-webkit-scrollbar {
display: none; /* 不显示滚动条 */
}
/*滚动元素,需要设置scroll才能隐藏*/
.scorllEle{
position: absolute;
width: 100vw;
height: 100vh;
overflow-x: hidden;
overflow-y: scroll;
}
6、滚动-定义滚动条样式
/*css主要部分的样式*/
/*定义滚动条宽高及背景,宽高分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar {
width: 10px; /*对垂直流动条有效*/
height: 10px; /*对水平流动条有效*/
display: none; /* 不显示滚动条 */
}
/*定义滚动条的轨道颜色、内阴影及圆角*/
::-webkit-scrollbar-track{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
background-color: rosybrown;
border-radius: 3px;
}
/*定义滑块颜色、内阴影及圆角*/
::-webkit-scrollbar-thumb{
border-radius: 7px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
background-color: #E8E8E8;
}
/*定义两端按钮的样式*/
::-webkit-scrollbar-button {
background-color:cyan;
}
/*定义右下角汇合处的样式*/
::-webkit-scrollbar-corner {
background:khaki;
}
7、设置父dom根据多个子dom自动变宽
.father {
display: inline-block;
white-space: nowrap; //这个很关键,没有设置这个的话,如果超过屏幕宽度则自动换行,导致dom没有自动变宽。
}
.son {
display: inline-block;
white-space: nowrap;
}
8、取消ios橡皮筋效果
方法1:设置元素position:fixed;
方法2:
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
9、设置图片无法被长按选中与保存
img {
user-select: none;
pointer-events: none;
}
10、设置图片与文字一起上下居中
即使文字换行也是哦
.imWrapper {
position: relative;
width: 520px;
border-radius: 29px;
background-color: rgba(0, 0, 0, 0.3);
padding:8px 20px;
box-sizing: border-box;
margin-bottom: 10px;
img {
width: auto;
height: auto;
vertical-align: middle;
margin-right: 8px;
}
span {
vertical-align: middle;
}
}
<div class='imWrappe'>
<img src='a.png' alt="" />
<span>哈哈哈哈哈哈哈哈哈哈哈哈哈</span>
</div>
11、css跑马灯
12、css设置c元素自适应父元素剩余高度
a、b元素固定高度、c元素自适应剩余高度。c元素的子内容能够滚动。
.father {
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
.a,.b {
position: relative;
width: 100%;
min-height: 118px;
}
.c {
position: relative;
width: 100%;
border:20px solid black;
flex: 1;
overflow-y: scroll;
.cLongContent {
position: relative;
height: 200vh;
background: linear-gradient(to bottom, #ff0000, #0000ff);
}
}
}
<div class='father'>
<div class='a'></div>
<div class='b'> </div>
<div class='c'><div class='cLongContent'></div></div>
</div>
13、BetterScroll 2.0遇到的坑
ios13.4移动端无法滚动,其他都可以滚动。原因是BetterScroll的css代码
!
.BetterScroll {
position: relative;
width: 710px;
height: 100%;
// display: flex;
// flex-direction: column;
// align-items: center;
overflow: hidden;
.conetent {
position: relative;
width: 710px;
height: 2000px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
}
注释掉:BetterScroll的如下代码即可!
// display: flex;
// flex-direction: column;
// align-items: center;
js常用设置
1、lottie的动画监听
例如使用了lott.playSegments([248, 348], true);循环播放,但是如果用enterFarme来监听执行的最后一帧会有误差,有空还没执行到最后一帧,它就重新播放了。
解决方法:使用loopComplete
lott.addEventListener("loopComplete", () => {
if(this.animationRuning){
this.lott.playSegments([10, 100], true);
this.animationRuning = false;
this.lott.removeEventListener("loopComplete");
resolve();
}
});
2、滚动-ios在全屏滚动下偶尔会出现无法滚动情况
当给全屏元素设置scroll的时候,里面的内容在滚动的时候ios偶尔会出现无法滚动,不操作几秒才会恢复的情况。
.scroll {
position: absolute;
width: 100vw;
height: 100vh;
overflow: hidden;
overflow-y: scroll;
.scrollContent {
position: relative;
width: 100vw;
height: 200vh;
}
}
解决方法:使用BetterScroll 2.0;
3、滚动到指定元素位置
指定元素.scrollIntoView(true)