【已解决】安卓手机测试发现至少需要手指点击页面任何部分之后返回才会触发popstate

495 阅读1分钟

需求

平台用户把自己的文章分享出去,别人打开后点击物理(手势)返回引导去首页查看更多的内容

实现方案一(有瑕疵)

此方案存在的问题,打开页面需要点击一下页面内容才能触发 popstate 事件

document.addEventListener('DOMContentLoaded', function () {
  const redirectToIndexUrl = 'http://www.baidu.com'

  const pushHistory = () => {
    const state = {
      url: '#forward'
    }
    window.history.pushState(state, null, '#forward')

    const handleRedirect = () => {
       if (location.hash.includes('#forward')) {
          return
        }

      window.location.replace(redirectToIndexUrl)
    }

    window.addEventListener('hashchange', handleRedirect)
    window.addEventListener('popstate', handleRedirect)
  }

  pushHistory()
})

实现方案二(完美解决问题)

此方案完美解决了我的需求,目前测试了 iOS、小米、华为部分设备均可正常执行

const redirectToIndexUrl = 'http://www.baidu.com'
document.addEventListener('DOMContentLoaded', function () {
  const go = function (url) {
    const aElement = document.createElement('a')
    aElement.href = url
    aElement.rel = 'noreferrer'
    document.body.appendChild(aElement)
    aElement.click()
  }

  // 监听手机物理返回,引导用户返回首页
  const goBack = (url, cb) => {
    if (
      history.pushState(
        history.length + 1,
        'message',
        window.location.href.split('#')[0] + '#' + (new Date).getTime()
      ),
      history.pushState(
        history.length + 1,
        'message',
        window.location.href.split('#')[0] + '#' + (new Date).getTime()
      ),
      -1 !== navigator.userAgent.indexOf('Android')
    ) {
      if ('undefined' !== typeof window.tbsJs) {
        window.tbsJs.onReady('{useCachedApi : true}', function () {})
        window.onhashchange = function () {
          const timer = setTimeout(function () {
            go(url), clearTimeout(timer)
          }, 10)
          cb && cb()
        }
        window.addEventListener('popstate', function () {
          const timer = setTimeout(function () {
            go(url), clearTimeout(timer)
          }, 10)
          cb && cb()
        })
      } else {
        let index = 0
        window.onhashchange = function () {
          if (++index > 3) {
            const timer = setTimeout(function () {
              go(url), clearTimeout(timer)
            }, 10)
            cb && cb()
          } else {
            history.go(1)
          }
        }
        history.go(-1)
        window.addEventListener('popstate', function () {
          if (index > 3) {
            const timer = setTimeout(function () {
              go(url), clearTimeout(timer)
            }, 10)
            cb && cb()
          }
        })
      }

    } else {
      window.onhashchange = function () {
        const timer = setTimeout(function () {
          go(url), clearTimeout(timer)
        }, 10)
        cb && cb()
      }
      window.addEventListener('popstate', function () {
        const timer = setTimeout(function () {
          go(url), clearTimeout(timer)
        }, 10)
        cb && cb()
      })
    }
  }

  goBack(redirectToIndexUrl)
})