H5开发问题汇总

flex不会缩短至小于内容框尺寸导致内容溢出

默认情况下,元素不会缩短至小于内容框尺寸,若想改变这一状况,需要设置元素的min-width与min-height属性

<div class="flex"><div class="f1 minW0">minH0 或 minW0 配合 f1 同时使用</div></div>

.flex {
  display: flex;
}
.f1 {
  flex: 1;
}
.minH0 {
  min-height: 0;
}
.minW0 {
  min-width: 0;
}

iOS手机H5下拉遮挡内容问题解决方案

原因:由于iOS的弹性滚动(overscroll)特性导致的,解决方案如下

1、设置meta标签viewport

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover, user-scalable=no" />

2、body宽高100%,并且禁止滚动,解决iOS上拉下拉白色底色遮挡,已经影响功能滚动的问题

html,
body {
  /*滚动事件发生在 html 元素上;JS 中可以监听 html 的滚动*/
  overflow-y: hidden;
  /*body 宽度大 html 度时,某些浏览器会出现内部滚动条;所以设置「html、body」宽度相同且「overflow-x: hidden」*/
  overflow-x: hidden;
  width: 100%;
  /*让 html 和浏览器窗口高度一致*/
  height: 100%;
  /*少数浏览器默认背景色为浅灰色,所以设置默认背景颜色为纯白*/
  background-color: #FFF;
  /*取消部分浏览器点击有阴影*/
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

3、功能模块内滚动按需使用以下公共样式处理

.scrollX {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overflow-scrolling: touch;
  overflow-x: scroll;
}
.scrollY {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overflow-scrolling: touch;
  overflow-y: scroll;
}

iOS系统中transform: translate3d()会超出父级overflow: hidden的限制

iOS的WebKit引擎在处理3D变换时会将元素提升到一个新的渲染层,这会导致:
1.元素脱离常规文档流
2.忽略父容器的溢出裁剪
3.特别是在Safari和iOS WebView中表现明显

/* 添加 z-index 和 will-change 属性 */

.parent {
  overflow: hidden;
  position: relative;
  z-index: 1; /* 创建新的堆叠上下文 */
}

.child {
  transform: translate3d(0, 50px, 0);
  will-change: transform;
}

高德地图相关问题

高德地图使用html2canvas截屏空白问题,配置WebGLParams可解决

new AMap.Map(this.container, {
  // 配置WebGLParams
  WebGLParams: {
    preserveDrawingBuffer: true,
  },
})

配置WebGLParams后会导致修改地图主题无效的问题

// 强制开启webgl,解决地图截屏启用的webgl配置后修改地图主题无效的问题
// @ts-ignore
window.forceWebGL = true

高德地图初始化报警告
Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true

/**
 * 优化高德地图初始化并解决 Canvas2D 警告
 */
export const patchCanvasContext = (): void => {
  const originalGetContext = HTMLCanvasElement.prototype.getContext
  // @ts-ignore
  HTMLCanvasElement.prototype.getContext = function (
      type: string, 
      attributes: CanvasRenderingContext2DSettings = {},
  ): RenderingContext | null {
      if (type === '2d') {
        // 告诉浏览器这个Canvas会被频繁读取,浏览器会优化内存管理
        attributes.willReadFrequently = true
      }
      return originalGetContext.call(this, type, attributes)
  }
}

// 使用,地图实例化前调用
patchCanvasContext()
new AMap.Map(this.container, {
  zoom: 13,
  center: [116.397428, 39.90923],
  ...options,
})

jsBridge相关问题

如果android回调是以下方式调用,应避免同时或短时间内多次调用
❗注意:由于回调是异步,如果同时调用或短时间内多次调用会覆盖回调函数,导致前面定义的回调处理失效

// 避免同一时刻多个地方多次与android交互,开发时要注意,尽量避免
export const test = (callback: Function) => {
  if (isAndroid) {
    // 调用android方法
    window.android?.func()
    // 回调,此处有大坑
    // 如果是多个地方调用,这里的回调会被覆盖,导致无法拿到android返回的结果
    window.receiveFunc = (result: any) => {
      console.log(result)
      callback?.()
    }
  }
}

App中webview相关

app打开h5出,出了必要参数,顶部、底部安全区域最好是由app通过url传递给h5,h5持久化到store及本地中

// 建议webview全屏,页面全部由H5处理
// app在webview中首次打开H5需要在url中传递参数
token // app登录的token,bearer eyJhbGci****
sat // 顶部状态栏安全区域高度 (不传默认0)(为处理部分老机型兼容性问题)
sab // 底部安全区域高度(不传默认0)(为处理部分老机型兼容性问题)
// 全局变量
:root {
  --safe-area-inset-top: constant(safe-area-inset-top);
  --safe-area-inset-top: env(safe-area-inset-top);

  --safe-area-inset-bottom: constant(safe-area-inset-bottom);
  --safe-area-inset-bottom: env(safe-area-inset-bottom);
}

// 覆盖vant-ui中顶部安全区域
.van-safe-area-top.van-safe-area-top {
  padding-top: var(--safe-area-inset-top);
}

// 覆盖vant-ui中底部安全区域
.van-safe-area-bottom.van-safe-area-bottom {
  padding-bottom: var(--safe-area-inset-bottom);
}

// 定义业务中顶部安全区域全局样式类
.safeAreaTop {
  padding-top: var(--safe-area-inset-top);
}

// 定义业务中底部安全区域全局样式类
.safeAreaBottom {
  padding-bottom: var(--safe-area-inset-bottom);
}
const route = useRoute()

// 顶部、底部安全区域高度
const safeAreaTop = ref<number>(0)
const safeAreaBottom = ref<number>(0)
const setSafeAreaSize = () => {
  const top = route.query?.sat?.toString()
  const bottom = route.query?.sab?.toString()
  if (top) {
    setSafeAreaTop(+top)
    safeAreaTop.value = +top
  } else {
    safeAreaTop.value = globalState.safeAreaTop
  }
  if (bottom) {
    setSafeAreaBottom(+bottom)
    safeAreaBottom.value = +bottom
  } else {
    safeAreaBottom.value = globalState.safeAreaBottom
  }
  try {
    document.body.style.setProperty('--safe-area-inset-top', `${safeAreaTop.value}px`)
    document.body.style.setProperty('--safe-area-inset-bottom', `${safeAreaBottom.value}px`)
  } catch (error) {
  }
}
import { defineStore } from 'pinia'

// 全局变量
const STORE_KEY = 'globalStore'
const useGlobalStore = defineStore(
  STORE_KEY,
  () => {
    const globalState = reactive({
      // 顶部安全区域高度
      safeAreaTop: 0,
      // 底部安全区域高度
      safeAreaBottom: 0,
    })
    const setSafeAreaTop = (height: number) => {
      globalState.safeAreaTop = height
    }
    const setSafeAreaBottom = (height: number) => {
      globalState.safeAreaBottom = height
    }
    return {
      globalState,
      setSafeAreaTop,
      setSafeAreaBottom,
    }
  },
  // 开启数据持久化
    {
        persist: {
            key: STORE_KEY,
            storage: localStorage,
        }
    }
)

export default useGlobalStore
© 2024 www.wdg.pub all right reserved Last modified: 2025-08-09

results matching ""

    No results matching ""