h5页面嵌套在app中遇到的问题记录

css满屏问题

设置html
屏幕上安全距离: safe-area-inset-top 屏幕右安全距离: safe-area-inset-right 屏幕下安全距离: safe-area-inset-bottom 屏幕左安全距离: safe-area-inset-left
设置html
默认:viewprot-fit:contain;页面内容显示在safe area内

ios手机点击页面返回的时候都是返回到上一层页面的顶部,而不是返回之前页面滑动的位置

在页面被销毁的生命周期componentWillUnmount记录页面的scrollTop的数值然后在componentDidMount将之前记录的scrollTop赋值给当前页面元素

在页面全局被设置了安全区域的时候,某一个页面的按钮需要在页面的底部展示

设置button{position:fixed;buttom:0}在安卓手机和苹果手机没有小刘海的手机上是ok的,但是在ios11+的系统上按钮并没有设置到最底部,需要给当前页面设置一个高度直接用100vh的时候,页面会出现滚动条,如果设置了安全区域的话,需要把安全区域和标题栏的高度去掉然后就可以了
height:calc(100vh - env(safe-area-inset-top) - 46px )//针对ios11.2+
height:calc(100vh - constant(safe-area-inset-top) - 46px )//针对ios11.2

react项目中防止按钮重复点击,重复进入新页面

就是按照正常思路来写(额外加一个setTimeout)
this.state = { canClick:true } handleChange = ()=>{ const { canClick } = this.state; const that = this; if(canClick){ this.setState({canClick:false}) //逻辑代码 //定时器异步恢复按钮的可点击性 setTimeout(()=>{ ttat.setState({ canClick:true }) },10) } }

react项目中使用echarts

如果echarts没有tooltip,尽管设置了也不起作用,可能是需要单独引入tootip的文件

import 'echarts/lib/component/tooltip';

echarts富文本用法:
formatter:'{className1|{value}}{className2|常量}'
柱状图数据多的情况下(超过100条)ios手机上不显示图表
搜了一下是因为渲染的柱状图的宽
高的面积超过了canvas画布的最大面积
Canvas area exceeds the maximum limit (width * height > 16777216).
解决方案:看了一下echarts的官网echarts4.0以上的可以用svg来画图表
import 'zrendered/lib/svg/svg' let myChart = echarts.init(chart,null, { renderer: 'svg});
或者
let myChart = echarts.init(chart,null, { devicePixelRatio: 2});


echarts雷达图实现总值在最中间显示,最里面的一层用白色打底,如果需要显示层级关系则可以使用echartsZ属性,在series中有多个对象,每一个对象设置Z的值,可以参考官方文档

h5页面嵌套在app中遇到的问题记录_第1张图片
image.png

option = { title: { text: '88', x: 'center', y: 'center', textStyle: { color: '#333', fontWeight: 'bolder', fontSize: 64, } }}

在定义的option中加一个title的属性即可,至于中间的白色五边形,可以设置每一个值都一样然后设置区域颜色为白色

series:[{
  type:"radar",
  z:2,
animation:false,
silent:true//图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。
data:[{
 value:[],
 itemStyle:{
   normal:{}
 },
 areaStyle:{color:"blue",opacity:0.6}
},//蓝色区域
},{
  type:"radar",
  z:4,
animation:false,
silent:true//图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。
data:[
{
  value:[],
  itemStyle:{
  normal:{}
},
areaStyle:{color:"#fff",opacity:1}
}//白色区域]
}]

网络不好的情况下,在同一个canvas容器中切换不同数据的图表切换的时候会出现图表的动画效果触发两次,原因:option的值从请求接口重新获取,react的setState是异步赋值option,切换按钮会导致按钮的setState,触发render,此时option还是原来的数据echarts会执行setOption,因为echarts图表设置animation:true,所以会出现动画,等option的值被替换成最新的内容的时候会触发setOption,重新渲染的时候也会有动画效果,所以才造成两次动画效果
解决方案:
1.可以把动画效果屏蔽掉animation:false
2.设置两种状态currentSelect,lastedStatus

const option = {radar:{},series:[
  {type:"radar"}
]}
handleChange = (type)=>{
    this.setState({
        currentSelect:type//记录按钮切换的状态
    })
this.loadMore(type)
}
loadMore = (type)=>{
    func().then((res)=>{
        if(res.code === 200){
            option.series[0].data[0].value = res.data;
           this.setState({
              lastedStatus:type//记录option更新状态
              option:option
            })
       }
     })
}
render(){
  if(this.state.currentSelect === this.state. lastedStatus){
      myChart.setOption(this.state.option)
   }
}
页面切换的时候出现闪屏,页面无法更新

用amtd-mobile的tabs将多个页面拼凑成一个页面就不会出现闪屏问题
但是切换tabs的时候有的页面会更新不及时,我的解决方案:
{currentPage==="1"?:""} {currentPage==="2"?:""} {currentPage==="3"?:""}
在监听tabs切换的事件中更新currentPage的值

有的样式在手机上不起作用

根据兼容性给样式添加-webkit-
-webkit-flex:1; flex:1

h5页面唤起app成功之后重新回到h5页面依然会执行下载app

先判断h5运行的环境分为三种

var u = navigator.userAgent;
let isWeixin= u.toLowerCase().indexOf('micromessenger')!== -1;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); 
let hasApp=false;
if(isWeixin){
  //提示需要在浏览器里面运行,因为微信自带的浏览器无法用配置的url scheme唤起app
alert("请在浏览器运行词链接")
}else{
  if(isAndroid ){
      window.location.href = "唤起app的url"//URL Scheme方式唤起Activity或App
  //判断是否唤起成功,只有失败的时候才会执行下载apk的代码
    this.checkOpen((opened)=>{
        if(!opened){ hasApp = false;//系统没有此app,唤起失败}else{
            hasApp = true;
      }
    })
      setTimeout(()=>{
      let hidden = window.document.hidden;
      if(typeof hidden === "undefined"||hidden === false&&!hasApp){
        window.location.href = "下载apk的url地址"
    }
    },2000)
    }
  if(isIOS){ //ios等同于安卓的写法}
}
//判断是否唤起app
checkOpen = (cb)=>{
    const clickTime = +(new Date());
    function check(elseTime){
        if(elseTime>3000||document.hidden){cb(true)}else{cb(false)}
    }
   let count = 0;let intHandle = null;
    intHandle = setTiterval(()=>{
        count++;
        const elseTime = +(new Date()) - clickTime;
        if(count>100||elseTime>3000){
            clearInterval(intHandle );check(elseTime)   
       }
    },20)
}

这个解决方案也是我百度参考了网上写的文章:
https://www.jianshu.com/p/21380058d609
https://www.cnblogs.com/shoestrong/p/9436722.html
另外一种方案就是借助callapp-lib插件,
在苹果手机上可以设置timeout:0,可以避免长时间唤起app失败自动跳转App store的问题
安卓手机的话,测试了小米,三星,vivo,华为,只有华为手机还是在长时间唤起app没跳转之后自动下载app,其他的手机会刷新一下当前页面

h5页面实现slider两边滑动的效果

image.png

antd-mobile里面有个Range的组件,但是看了一下没有tooltip显示当前滑动的数值,在网上搜了一个适合react的滑动插件 rc-slider,api上面介绍了该插件的多种用法,我在项目中使用的是 Range

 `${value}`}
       tipProps={
           {"prefixCls": 'rc-slider-tooltip',
               "placement": 'top',
               "visible": true//设为true显示数值的tooltip就会一直存在
           }
       }
       value={[creditScoreStart,creditScoreEnd]}
onChange={(e)=>{
  this.setState({
  creditScoreStart:e[0],
  creditScoreEnd:e[1]
})}}
 marks={marks}
/>

api文档上面tipProps属性中没有包含“visible”这个配置,但是源码中是有这个配置的入口的,所以加了“visible”是起作用的

ant mobile 的 ListView 组件加载一定数据后,点击详情返回回到之前的滚动条的滚动位置(onEndReached上滑到底部和页面初始话的时候请求数据,可以定义一个公共的方法this.loadMore()获取数据)

参考网上解答

react项目中在不使用npm run eject的情况下按需引入Antd以及less

安装customize-cra,引入react-app-rewired插件:react-app-rewired的作用就是在不eject的情况下,覆盖create-react-app的配置

npm install react-app-rewired customize-cra babel-plugin-import
npm install less less-loader

在根目录下面新建config-overrides.js,并修改相关配置

const { override, fixBabelImports,addLessLoader,addWebpackAlias } = require('customize-cra');
const path = require("path");
module.exports = override(
  fixBabelImports("import", {    //配置按需加载
    libraryName: "antd-mobile",    
    libraryDirectory: "es",    
    style: true, //自动打包相关的样式 默认为 style:'css'  
  }),
  // 使用less-loader对源码重的less的变量进行重新制定,设置antd自定义主题  
 addLessLoader({
        lessOptions: {
          javascriptEnabled: true,
          modifyVars: { '@primary-color': '#1DA57A' },
        },
      }),
  //增加路径别名的处理 
  addWebpackAlias({  
    'root': path.resolve('./src')  
  })
); 

你可能感兴趣的:(h5页面嵌套在app中遇到的问题记录)