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'
|
|
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
|