Webview网页踩坑记录

2,863 阅读3分钟

1 安卓端location.replace无效解决办法

function locationReplace(url) {
	try {
		if (window.history.replaceState) {
			window.history.replaceState(null, document.title, url);
			window.history.go(0);
		} else {
			window.location.replace(url);
		}
	} catch (error) {
		window.location.href = url;
	}
}

2 安卓客户端只支持特定的标签

有时候,客户端需要显示标签字体样式,但是安卓端只支持特定的标签,这个时候可以参考这个回答

3 iOS刘海屏CSS安全距离

3.1 方案一

  1. 设置网页在可视窗口的布局方式
<meta name="viewport" content="width=device-width, viewport-fit=cover" />
  1. 设置安全区域
  .page {
    /* ios < 11.2 */
    padding-left: constant(safe-area-inset-left);
    padding-top: constant(safe-area-inset-top);
    padding-right: constant(safe-area-inset-right);
    padding-bottom: constant(safe-area-inset-bottom);
    /* ios >= 11.2 */
    padding-left: env(safe-area-inset-left);
    padding-top: env(safe-area-inset-top);
    padding-right: env(safe-area-inset-right);
    padding-bottom: env(safe-area-inset-bottom);
  }

上述效果如不理想请看3.2内容

3.2 刘海屏适配方案二

  1. 设置网页在可视窗口的布局方式
<meta name="viewport" content="width=device-width, viewport-fit=cover" />

2.scss设置mixin

@mixin iphoneX() {
  /*iPhone X 适配*/
  @media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) {
    @content;
  }
  /*iPhone XR 适配*/
  @media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 2) {
    @content;
  }
  /*iPhone XS max 适配*/
  @media only screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) {
    @content;
  }
  @media only screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) {
    @content;
  }
}

3 使用

.wrap {
  padding-top: 60px;
  @include iphoneX {
    padding-top: calc(constant(safe-area-inset-top) + 46px);
    /* ios >= 11.2 */
    padding-top: calc(env(safe-area-inset-top) + 46px);
  }
}

4 SVG transform 在Safari 11中不起作用

<svg width="1000" height="500" transform="rotate(180)">...</svg>

在Safari 11中显示为未旋转。

解决办法:用CSS style属性代替

<svg width=“1000” height=“500” style =“transform:rotate(180deg)”>

5 iOS滚动遮挡底部fix元素问题

5.1 方式一

通过阻止touchmove事件,这种杀伤力很大,页面所有内容都不能滚动

  /** 阻止底部滚动 */
  useEffect(()=>{
    const touchMoveFn = (e)=>{
        // 阻止默认事件
        e.preventDefault();
    }

    document.body.addEventListener('touchmove', touchMoveFn, { 
      passive: false
    });

    return ()=>{
      document.body.removeEventListener('touchmove', touchMoveFn,false)
    }
  },[])

5.2 方式二

HTML结构:html>body>.wrap>.content

通过CSS设置html,body,.wrap元素overflow:hidden

.content元素设置

  width: 100%;
  max-height: 100%;
  box-sizing: border-box;
  overflow: auto;
  -webkit-overflow-scrolling:touch;

如果存在自定义导航栏,可通过获取导航栏高度,js动态设置 .wrap paddingTop

5.3 方式三:页面布局flex + 100vh 方案

注意点 1:

首先注意100vh在safaria环境下有坑 [链接],但是我们是在APP的webview环境,所以使用vh暂无影响

注意点 2:

父元素flex:1,子元素设置height:100%无效。需要设置 父元素display:flex;flex-direction:column; ,子元素再设置一遍flex:1撑满高度

代码部分:

情况一

html部分:

div.wrap>div.header+div.wrapBody+div.footer

css部分:

.wrap{
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;

    background: rgba(0,0,0,0.8);
}
.wrapBody{
    flex: 1;
    overflow: auto; // 需要滚动的地方记得设置 overflow: auto; -webkit-overflow-scrolling:touch;
    -webkit-overflow-scrolling:touch;
}

情况二

html部分:div.wrapBody 存在唯一子元素情况下

div.wrap>div.header+div.wrapBody>div.child>div.children+div.footer

css部分:

.wrap{
    height: 100vh;
    display: flex;
    flex-direction: column;
}
.wrapBody{
    flex: 1;
    overflow: hidden;

    // 父元素flex:1,子元素设置height:100%无效。需要设置 父元素display:flex;flex-direction:column; ,子元素再设置一遍flex:1
    display:flex;
    flex-direction:column;
    &>*{ // 必须只有一个子元素
        flex: 1;
        overflow: auto; // 需要滚动的地方记得设置 overflow: auto; -webkit-overflow-scrolling:touch;
        -webkit-overflow-scrolling:touch;
    }
}

6 iOS input输入框样式重置

input{
    // iOS上边框线有阴影
    -webkit-appearance: none; 
    // placeholder不垂直居中
    line-height:normal;
}
input:disabled{
    // fix:在input框中加入disabled=”disabled”之后,字体默认的就变成灰色
    opacity: 1;
}

7 iOS输入框失去焦点下面出现空白问题

需要在键盘收起的 blur 事件中,使用 window.scrollTo 让页面回到原位置即可。链接

8 iOS时间戳 NaN 问题

IOS中不支持 - 连接日期

需要写成

var time = new Date("2020-02-20 12:00:00".replace(/-/g, "/"));

这样来兼容iOS

new Date("2020-02-20T23:00:00")在iOS safari有坑,new Date("2020-02-20T23:00:00")会转成 2020-02-21 下一天日期

9 设置小字体

一般字体最小为12px,所以为了展示更小字体,需要借助transform,

div>span{
    display: inline-block;  // 如果是 display: inline; 则transform设置会无效
    font-size: px2rem(12);
    transform: scale(0.8);
}