H5 positioning the ultimate solution

H5 positioning the ultimate solution for
the background
to make a micro-H5 mall, mainly in the micro-letters, but also taking into account other browsers. Among them, home need to find the nearest store based on the current user's latitude and longitude and display. The front end needs to be done is to get the user's latitude and longitude and then query the back-end interfaces and rendering the page.

Objective analysis and
our goal is after the package, only need to call a method you can get location information returned.
We need to do is, for different end (H5 and other micro-channel browser environment) package different classes, and then by a method to distinguish between UA, call category corresponding to different environmental acquisition position.
Inside the micro-channel, after much practice, whether through HTML5 Target native, or jsapi acquired by a third party (such as Baidu or Tencent map) position, not only positioning for a long time, the case of failure to locate or even often, seriously affecting the user experience , especially for most of the information flow are dependent on the Mall Home for the location, it is totally unacceptable. So in the micro-channel micro-channel sdk which we have only one option;

As for the browser, or through third-party maps jsapi positioning components can be stable and relatively fast access to location information, in order to try to be consistent with the micro letter, we chose Tencent map jsapi.

Solution
Talk is cheap, show me the code ado, directly on the code:

  1. In the browser, acquired by Tencent location map jsapi
    1.1 introduced in the html template file for the project Tencent map jsapi
    <- - index.html!>
    <Script charset = "UTF-8" src = " HTTPS: // the Map .qq.com / api / js v = 2.exp & key = key & referer = Tencent Maps application name "> </ Script>? ;
    Description:

Use the map Tencent jsapi, need to go to the map Tencent open platform to apply its own account, and then create their own applications, Tencent will replace the value above the map key and application name created.

1.2 Get location interface call, obtain location information
in order to facilitate multiplexing, we individually packaged Tencent map jsapi a class named tMap.js

TMap.js //
const = QQ window.qq
var Geolocation null =
IF (QQ && qq.maps) {
// Initialization positioning assembly
Geolocation = new new qq.maps.Geolocation (
'QVLBZ-YUULR-OUMW7-WKXFD-4SUWS-UDBIA ',
' myMap '
)
}

the TMap {class
// Get the location counter does not continue for more than 3 times the total number of times when the location fails, an error is thrown location fails
getPositionCount = 0

// Get the external location interface exposed
getLocation () {
return new new Promise ((Resolve, Reject) => {
// positioning success callback
this.getTMapLocation (Resolve, Reject)
})
}

// Call Tencent acquired location map
getTMapLocation (Success, Fail) {
const = _self the this

// 定位成功回调
const showPosition = position => {
  uni.setStorage({
    key: 'positionData',
    data: position
  })
  success(position)
}

// 定位失败回调
const showErr = (err) => 
  // 如果获取定位失败超过3次 抛出错误 否则继续获取定位信息
  if (this.getPositionCount > 3) {
    fail('超过3次 获取定位失败')
  } else {
    // 定位失败递归
    _self.getPositionCount = _self.getPositionCount + 1
    _self.getTMapLocation(success, fail)
  }
}

// 调用腾讯web定位组件获取位置信息
if (geolocation) {
  geolocation.getIpLocation(showPosition, showErr, {
    timeout: 6000,  // 定位超时时长 单位ms
    failTipFlag: true
  })
}

}
}

export default new TMap()

  1. In the micro-channel webview, the micro-channel by acquiring location information SDK
    2.1 micro channel js-sdk related preparations
    2.1.1 introduced js file
    / **
    • Micro-channel asynchronous loading sdk
    • @param {*} src
    • @param {} callback api接口
      /
      export const handlerLoadScript = callback => {
      const src = https://res.wx.qq.com/open/js/jweixin-1.4.0.js
      if (!(typeof callback === 'function')) {
      callback = function() {}
      }
      var check = document.querySelectorAll(script[src="${src}"])
      if (check.length > 0) {
      check[0].addEventListener('load', function() {
      callback()
      })
      callback()
      return
      }
      var script = document.createElement('script')
      var head = document.getElementsByTagName('head')[0]
      script.type = 'text/javascript'
      script.charset = 'UTF-8'
      script.src = src
      if (script.addEventListener) {
      script.addEventListener(
      'load',
      function () {
      the callback ()
      },
      to false
      )
      } the else IF (script.attachEvent) {
      script.attachEvent ( 'the onreadystatechange', function () {
      var target = window.event.srcElement
      IF (target.readyState === 'loaded ') {
      callback ()
      }
      })
      }
      head.appendChild (Script)
      }
      2.1.2 injection authority to verify the configuration
      of all pages need to use the JS-SDK must first injection configuration information, otherwise it will not be called. Usually is the interface for configuration information through the background.

/**

  • Injection authority to verify the configuration
  • @param {object} micro-channel configuration js-sdk privilege verification
    * /
    Export wxconfigInfo = config = const> {
    wx.config ({
    Debug: to false, // debug mode is turned on, all calls will return values api out alert client , to see the incoming parameters, you can open the pc side, will play parameter information through log, will be printed only when the pc.
    appId: config.appId,
    timestamp: parseInt (config.timestamp),
    nonceStr: config. nonceStr,
    Signature: config.signature,
    jsApiList: [// JSAPI list needs to use
    ...,
    'getLocation' // Get location
    ]
    })
    }
    2.2 acquiring location information call api
    / **
  • Micro-channel acquisition position
    * /
    Export handleGetLocation = const (config) => {
    return new new Promise ((Resolve, Reject) => {
    wxconfigInfo (config)
    wx.ready (function () {
    wx.getLocation ({
    type: 'WGS84', // default is wgs84 gps coordinates, if the coordinates to be returned directly to Mars openLocation used, can be passed 'gcj02'
    success: function (RES) {
    console.warn ( 'micro-channel sdk positioning success', RES)
    Resolve ({
    LAT : res.latitude, // Lat
    lng: res.longitude, // longitude
    speed: res.speed, // speed, in meters / second meter
    accuracy: res.accuracy // positional accuracy
    })
    },
    Fail: function ( ERR) {
    console.error ( 'micro-channel sdk location failure', ERR)
    Reject (ERR)
    }
    })
    })
    wx.error (function (ERR) {
    // config information validation fails performs error function, such as a signature expired authentication failures, specific error message can open the debug config mode viewing, can also be viewed in the res parameter returned for the SPA where you can update signatures.
    the console.log ( 'wxjsapi-error =', ERR)
    Reject ( wxjsapi-error: ${err})
    })
    })
    2.3 invoke different positioning methods according to the different operating environments
    // public.js

/**

  • Enumeration UA
    * /
    const UA = {
    / **
    • Micro-channel H5
      * /
      wechat: 'wechat',
      / **
    • Alipay H5
      * /
      ALIPAY: 'ALIPAY',
      / **
    • Other
      * /
      the OTHERS: 'the OTHERS'
      }

/**

  • Analyzing client runtime environment where only the browser and the micro-channel is determined H5
    * /
    Export getUserAgent const = () => {
    var = navigator.userAgent.toLowerCase the userAgent ()

    if (userAgent.match(/Alipay/i) == 'alipay') {
    return UA.ALIPAY
    } else if (userAgent.match(/MicroMessenger/i) == 'micromessenger') {
    return UA.WECHAT
    } else {
    return UA.OTHERS
    }
    }
    // js-sdk.js
    /**

  • Evokes micro-channel api
  • @param {*} _href current page url
  • @param {*} options share information
  • {@param } apiType type call api
    /
    Export handleWXSDKCall = const (_href, apiType, Options) => {
    return new new Promise ((Resolve, Reject) => {
    // interfaces for configuration information through the background
    WeChatServivce.sign (_href)
    . the then (RES => {
    IF (RES) {
    IF (apiType === 'LOCATION') {
    handleGetLocation (RES) .then ((RES) => {
    Resolve (RES)
    }). the catch (ERR => {
    Reject ( ERR)
    })
    }
    }
    })
    .catch (ERR => {
    Reject ( err-sign: ${err})
    uni.showToast ({
    title: err.data.code + err.data.msg,
    mask: to true,
    icon: 'none'
    })
    })
    })
    }
    // getLocation.js
    import { getUserAgent, handlerLoadScript } from '@/module/utils'
    import { handleWXSDKCall } from '@/module/utils/wechat/wxJsApiSdk'
    import UA from '@/module/enums/userAgent'
    import TMap from '@/module/utils/tMap'

/**

  • External exposure method of obtaining location
  • @return Promise resolve a target lat- positionData lng- latitude and longitude
    * /
    const getLocation = () => {
    return new new Promise ((Resolve, Reject) => {
    the console.log ( 'Enter the global user location acquisition method')
    const storageData uni.getStorageSync = ( 'positionData')
    const = getUserAgent the userAgent ()
    IF (storageData) {
    Resolve (storageData)
    } the else {
    // Tencent map using other positioning assembly according to the environment is determined if using a micro-channel in the micro channel sdk
    if (userAgent == UA.WECHAT =) {
    handlerLoadScript (() => {
    handleWXSDKCall (window.location.href, 'LOCATION'). the then ((RES) => {
    uni.setStorageSync ( 'positionData', RES)
    Resolve (RES)
    }) .catch (ERR => {
    Reject (ERR)
    })
    })
    } {the else
    TMap.getLocation ().then(res => {
    uni.setStorageSync('positionData', res)
    resolve(res)
    }).catch((err) => {
    reject(err)
    })
    }
    }
    })
    }

export default getLocation

  1. Page calls
    3.1 Vue bound to the prototype method
    Import from getLocation '@ / Module1 / utils / getLocation'
    Vue.prototype. GetLocation $ getLocation =
    3.2 assembly call page
    onShow () {
    // After obtaining the location information request back interfaces
    this . getLocation $ ()
    .then (RES => {
    console.warn ( 'Get home position success', RES)
    this.latitude = res.lat
    this.longitude = res.lng
    // this request back to the interface according to the obtained latitude and longitude ...
    })
    .catch (ERR => {
    console.error ( 'Get home location failure', ERR)
    // error handling
    })
    }

Summary
pit and point to note is encountered:

The use of micro-channel sdk obtain location information needed in order to complete the following steps:
asynchronous loading micro-channel sdk
for configuration information through the interface, configure the micro-channel sdk
call wx.ready callback method
must be in strict accordance with the order to complete the above three steps, otherwise it is impossible to call micro letter sdk functions.

In short, through this article, you can solve the H5 locate more than 99% of the scenarios.

Guess you like

Origin blog.51cto.com/14623707/2474710