H5开发中一些常见的问题

  1. 在设置页面禁止复制文本是,设置了-webkit-user-select: none导致iOS手机上输入框类失效
// index.html
* {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
// 排除input与textarea
[contenteditable="true"], input, textarea {
  -webkit-user-select: auto!important;
  -khtml-user-select: auto!important;
  -moz-user-select: auto!important;
  -ms-user-select: auto!important;
  -o-user-select: auto!important;
  user-select: auto!important;
}
  1. iPhoneX底部样式兼容,包括页面主体内容的在安全区域及fix定位下bottom: 0的兼容。参考:iPhone X兼容

  2. h5中拨号,采用window.open('tel:15000000000'),在iOS中不能使用。原因:iOS中不兼容window.open方法,通过window.location.href = 'tel:15000000000'来实现拨号操作

const isIos = function() {
  const isIphone = navigator.userAgent.includes('iPhone')
  const isIpad = navigator.userAgent.includes('iPad')
  return isIphone || isIpad
}

if (isIos) {
  window.location.href = 'tel:15000000000'
} else {
  window.open('tel:15000000000')
}
  1. 键盘遮挡输入框,onBlur方法监听处理
<input
  id='phone'
  type='tel'
  maxLength='11'
  placeholder='请输入'
  onChange={({ target: { value } }) => handlePhone(value)}
  onBlur={() => inputOnBlur()}
/>

const check = () => {
  setTimeout(() => {
    const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
    window.scrollTo(0, Math.max(scrollHeight - 1, 0))
  }, 100)
}

const inputOnBlur = () => {
  document.getElementById('phone').setAttribute('onblur', check())

  setTimeout(() => {
    window.scrollTo(0, document.body.scrollTop + 1)
    document.body.scrollTop >= 1 && window.scrollTo(0, document.body.scrollTop - 1)
  }, 100)
}
  1. 在react中使用类keep-alive组件在pc/h5中的使用 - react-live-route
  • 场景:长列表中滚动到很多页后查看了某条数据,进入列表详情,返回到列表页是,会回到顶部
  • 原因:react中进行路由跳转时,state等数据会丢失,也不回记录滚动等信息
  • 解决方式:
    - 采用redux等数据流工具,在列表页面跳转的时候在componentWillUnmount生命周期记录state中的数据与滚动位置信息,在componentDidMount生命周期对数据进行恢复、
    - 在路由跳转的时候隐藏列表页,在回到列表页的时候再重新渲染出来
  • 遇到的问题
    - Switch渲染的是匹配到的第一个路由,而LiveRoute是为了让组件强制渲染不匹配的路由
    - Switch与LiveRoute应包裹在同一个div中,不然会报错A may have only one child element
    - 采用position: absolute进行定位的元素会有影响
    - routes中的路由应该与keepRouter中的路由不重复,重复的情况下会在同一个路由下渲染页面两次
  • 参考链接
    - https://github.com/facebook/react/issues/12039
    - https://github.com/fi3ework/react-live-route
    - https://codesandbox.io/s/yj9j33pw4j?file=/src/index.js:399-409
    - https://zhuanlan.zhihu.com/p/59637392
 npm install react-live-route --save
// routes.js
export const routes = [
  {
    path: '/',
    exact: true,
    component: () => <Redirect to='/list' />
  },
  /*
  {
    path: '/list',
    exact: true,
    component: () => <DirectListPage />
  },
  */
  {
    path: '/create',
    exact: true,
    component: () => (
      <PermissionWrap>
        <DirectCreatePage />
      </PermissionWrap>
    )
  }
]
// 需要处理的路由列表
export const keepRouter = [
  {
    path: '/list',
    component: DirectListPage
  },
  {
    path: '/demand/list',
    component: DemandListPage
  }
]
// APP.js
import NotLiveRoute from 'react-live-route'
import { routes, keepRouter } from './pages/routes'

const LiveRoute = withRouter(NotLiveRoute)

<HashRouter>
  <>
    <Switch>
      {routes.map((item, index) => {
        return (
          <Route
            key={index}
            path={item.path}
            exact
            render={props => {
              if (canDirectLogin === true) {
                return <item.component {...props} />
              } else if (canDirectLogin === false) {
                return <ForbiddenPage />
              } else {
                return <Loading.Full />
              }
            }}
           />
          )
        })}
        </Switch>
        {keepRouter.map((item, index) => {
          return (
            <LiveRoute
              key={index}
              path={item.path}
              alwaysLive
              component={item.component}
              name={item.path}
            />
          )
        }
      )}
    </>
 </HashRouter>
  1. 微信H5重复授权
  • 问题描述
    - android手机上,主要在低版本的android机上,客户打开微信H5,页面出现多次弹出授权窗口,需要点击多次确认才会消失
  • 问题原因
    - 多次重定向导致出现多次授权窗口
    - hash模式路由导致的参数丢失
    - 授权链接中参数不完整
// 最终的重定向方法
// 去除重定向地址中的#,同时添加参数connect_redirect
redirectWXAuth = () => {
  const { goToPage } = this.state
  const url = (goToPage + '').replace('#', '')
  const redirectUrl = encodeURIComponent(
    `${process.env.REDIRECT_HOST}/login?goto_page=${encodeURIComponent(url)}&bindCode=1`
  )
  const wechatAuthUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${process.env.WXAPPID}&redirect_uri=${redirectUrl}&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect`
  window.location.replace(wechatAuthUrl)
}
原文地址:https://www.cnblogs.com/sk-3/p/13499677.html