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(), 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;