@vue-map/google
Version:
275 lines (191 loc) • 5.44 kB
JavaScript
// http://a.amap.com/jsapi_demos/static/remogeo/remogeo.js
function RemoGeoLocation() {
this._remoteSvrUrl = 'https://webapi.amap.com/html/geolocate.html'
this._callbackList = []
this._seqBase = 1
this._frameReady = 0
this._watchIdMap = {}
}
RemoGeoLocation.prototype = {
_getSeq: function() {
return this._seqBase++
},
_onRrameReady: function(callback) {
if (this._frameReady === 0) {
if (!this._frameReadyList) {
this._frameReadyList = []
}
this._frameReadyList.push(callback)
this._prepareIframe()
return
}
callback.call(this)
},
_prepareIframe: function() {
if (this._iframeWin) {
return
}
var ifrm = document.createElement('iframe')
ifrm.src = this._remoteSvrUrl +
(this._remoteSvrUrl.indexOf('?') > 0 ? '&' : '?')
ifrm.width = '0px'
ifrm.height = '0px'
ifrm.style.position = 'absolute'
ifrm.style.display = 'none'
ifrm.allow = 'geolocation'
var self = this
var timeoutId = setTimeout(function() {
self._frameReady = false
self._callbackFrameReadyList()
}, 5000)
ifrm.onload = function() {
clearTimeout(timeoutId)
self._frameReady = true
self._callbackFrameReadyList()
ifrm.onload = null
}
document.body.appendChild(ifrm)
this._iframeWin = ifrm.contentWindow
window.addEventListener('message', function(e) {
if (self._remoteSvrUrl.indexOf(e['origin']) !== 0) {
return
}
self._handleRemoteMsg(e['data'])
}, false)
},
_callbackFrameReadyList: function() {
if (this._frameReadyList) {
var list = this._frameReadyList
this._frameReadyList = null
for (var i = 0, len = list.length; i < len; i++) {
list[i].call(this, this._frameReady)
}
}
},
_pickCallback: function(seqNum, keepInList) {
var callbackList = this._callbackList
for (var i = 0, len = callbackList.length; i < len; i++) {
var cbkInfo = callbackList[i]
if (seqNum === cbkInfo.seq) {
if (!keepInList) {
callbackList.splice(i, 1)
}
return cbkInfo
}
}
},
_handleRemoteMsg: function(msg) {
var seqNum = msg['seq']
var cbkInfo = this._pickCallback(seqNum, !!msg['notify'])
if (cbkInfo) {
cbkInfo.cbk.call(null, msg['error'], msg['result'])
} else {
console.warn('Receive remote msg: ', msg)
}
},
_postMessage: function(cmd, args, callback, seq) {
this._prepareIframe()
var msg = {
'cmd': cmd,
'args': args,
'seq': seq || this._getSeq()
}
this._callbackList.push({
cbk: callback,
seq: msg['seq']
})
this._onRrameReady(function() {
if (this._frameReady === true) {
try {
this._iframeWin.postMessage(msg, '*')
} catch (e) {
this._pickCallback(msg['seq'])
callback(e)
}
} else {
this._pickCallback(msg['seq'])
callback({
'message': 'iFrame load failed!'
})
}
})
},
'getCurrentPosition': function(succHandler, errHandler, options) {
this._postMessage('getCurrentPosition', [options], function(err, result) {
if (err) {
if (errHandler) {
errHandler(err)
}
return
}
if (succHandler) {
succHandler(result)
}
})
},
'watchPosition': function(succHandler, errHandler, options) {
var watchKey = 'wk' + this._getSeq()
var cmdSeq = this._getSeq()
this._watchIdMap[watchKey] = {
stat: 0,
seq: cmdSeq
}
var self = this
this._postMessage('watchPosition', [options], function(err, result) {
var id = null
if (result) {
id = result['id']
}
var watchInfo = self._watchIdMap[watchKey]
watchInfo.id = id
watchInfo.stat = 1
if (watchInfo.callbackList) {
var list = watchInfo.callbackList
watchInfo.callbackList = null
for (var i = 0, len = list.length; i < len; i++) {
list[i].call(self, id)
}
}
if (err) {
if (errHandler) {
errHandler(err)
}
return
}
if (succHandler) {
succHandler(result['pos'])
}
}, cmdSeq)
return watchKey
},
'clearWatch': function(watchKey, callback) {
if (!this._watchIdMap[watchKey]) {
callback('Id not exists: ' + watchKey)
return
}
var watchInfo = this._watchIdMap[watchKey]
var self = this
function clearId(id) {
self._postMessage('clearWatch', [id], function(err, result) {
if (!err) {
self._pickCallback(watchInfo.seq)
delete self._watchIdMap[watchKey]
}
if (callback) {
callback(err, result)
}
})
}
if (watchInfo.stat < 1) {
if (!watchInfo.callbackList) {
watchInfo.callbackList = []
}
watchInfo.callbackList.push(function(id) {
clearId(id)
})
} else {
clearId(watchInfo.id)
}
}
}
export default RemoGeoLocation