首页 > 其他分享 >使用navigator.geolocation解决h5公众号定位不准确的问题

使用navigator.geolocation解决h5公众号定位不准确的问题

时间:2023-04-11 16:36:57浏览次数:44  
标签:geolocation return 定位 title h5 position uni navigator

封装js(utils/geolocation.min.js):

window.qq=window.qq||{},qq.maps=qq.maps||{},window.soso||(window.soso=qq),soso.maps||(soso.maps=qq.maps),qq.maps.Geolocation=function(){"use strict";var e=[],t=null,o=0,n="_geoIframe_"+Math.ceil(1e7*Math.random()),i=document.createElement("iframe"),r=null,s=null,a=null,c=null,u=function(u,l){if(!u)return void alert("请输入key!");if(!l)return void alert("请输入referer!");var p=document.getElementById(n);if(!p){i.setAttribute("id",n),i.setAttribute("allow","geolocation");var g="https:";i.setAttribute("src",g+"//apis.map.qq.com/tools/geolocation?key="+u+"&referer="+l),i.setAttribute("style","display: none; width: 100%; height: 30%"),document.body?document.body.appendChild(i):document.write(i.outerHTML);var m=this;window.addEventListener("message",function(n){var i=n.data;if(i&&"geolocation"==i.module){if(clearTimeout(c),e.length>0){var u=e.shift();u.sucCb&&u.sucCb(i)}o=2,m.executeNextGeo(),t&&t(i)}else{s=(new Date).getTime();var l=s-r;if(l>=a){if(e.length>0&&"geo"===e[0].type){var u=e.shift(),p={type:"fail",code:5,message:"The request"};u.errCb&&u.errCb(p)}clearTimeout(c),o=-1,m.executeNextGeo()}if(e.length>0&&"ip"===e[0].type){var u=e.shift();u.errCb&&u.errCb(p)}}},!1)}};return u.prototype.executeNextGeo=function(){1!==o&&e.length>0&&(o=1,e[0].geoprocess())},u.prototype.getLocation=function(t,n,i){if(i&&i.timeout){var r=new RegExp("^[0-9]*$");if(!r.test(i.timeout))return void alert("timeout 请输入数字")}if(e.length>10)throw new Error("geolocation queue must be lass than 10");e.push({sucCb:t,errCb:n,option:i,geoprocess:this.getOnceLocation,type:"geo"}),1!==o&&(o=1,this.getOnceLocation())},u.prototype.getOnceLocation=function(){var t=e[0]&&e[0].option;r=(new Date).getTime(),a=t&&t.timeout?+t.timeout:1e4,clearTimeout(c),c=setTimeout(function(){if(e.length>0){var t=e.shift();t.errCb&&t.errCb()}},a),document.getElementById(n).contentWindow.postMessage("getLocation","*")},u.prototype.getIpLocation=function(t,n){if(e.length>10)throw new Error("geolocation queue mast be lass than 10");e.push({sucCb:t,errCb:n,geoprocess:this.getOnceIpLocation,type:"ip"}),1!==o&&(o=1,this.getOnceIpLocation())},u.prototype.getOnceIpLocation=function(){document.getElementById(n).contentWindow.postMessage("getLocation.robust","*")},u.prototype.watchPosition=function(e){t=e,document.getElementById(n).contentWindow.postMessage("watchPosition","*")},u.prototype.clearWatch=function(){t=null,document.getElementById(n).contentWindow.postMessage("clearWatch","*")},u}();

精确定位使用:

<!-- 精确定位 -->
<template>
  <view>{{ positionInfo }}</view>
</template>

<script>
import '@/utils/geolocation.min.js';
export default {
  data() {
    return {
      positionInfo: ''
    };
  },
  onl oad(options) {
    this._initLocation();
  },
  methods: {
    _initLocation() {
      if (origin.indexOf('https') === -1) {
        uni.showToast({
          title: '请在https环境中使用'
        });
        return;
      }
      if (!navigator || !navigator.geolocation) {
        uni.showToast({
          title: '地理位置服务不可用'
        });
        return;
      }
      uni.showLoading({
        title: '定位中...',
        mask: true
      });
      const options = {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0
      };
      /** err 说明
				code 1  表示用户拒绝授权
				code 3  未获取到地址信息,可能是设备没有开启定位服务或者系统没有给浏览器定位权限
			**/
      navigator.geolocation.getCurrentPosition(
        (position) => {
          const lat = position.coords.latitude,
            lng = position.coords.longitude,
            geo = new qq.maps.Geolocation('地图api key', '获取位置信息');
          geo.getLocation(this.getLocationSuccess, this.getLocationErr, options);
        },
        (err) => {
          if (err.code === 1) {
            uni.showModal({
              title: '获取定位权限失败',
              content: '你拒绝了位置授权服务。请允许当前页面获取定位授权,后刷新页面。'
            });
          } else {
            uni.showModal({
              title: '获取定位权限失败',
              content: '请确定手机定位已打开,并且当前浏览器允许获取定位,都开启后请刷新页面。'
            });
          }
          uni.hideLoading();
        }
      );
    },
    getLocationSuccess(position) {
      uni.showToast({
        title: '定位成功!',
        duration: 1000
      });
      this.positionInfo = position;
      uni.hideLoading();
    },
    getLocationErr() {
      uni.showToast({
        title: '获取位置失败!',
        duration: 2000
      });
      uni.hideLoading();
    }
  }
};
</script>

  

效果:

                

 ip定位使用:

<!-- IP定位 -->
<template>
  <view>{{ positionInfo }}</view>
</template>

<script>
import '@/utils/geolocation.min.js';
export default {
  data() {
    return {
      positionInfo: ''
    };
  },
  onl oad(options) {
    this._initLocation();
  },
  methods: {
    _initLocation() {
      if (origin.indexOf('https') === -1) {
        uni.showToast({
          title: '请在https环境中使用'
        });
        return;
      }
      if (!navigator || !navigator.geolocation) {
        uni.showToast({
          title: '地理位置服务不可用',
          duration: 2000
        });
        return;
      }
      const options = {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0
      };
      uni.showLoading({
        title: '定位中...',
        mask: true
      });
      /** err 说明
				code 1  表示用户拒绝授权
				code 3  未获取到地址信息,可能是设备没有开启定位服务或者系统没有给浏览器定位权限
			**/
      navigator.geolocation.getCurrentPosition(
        (position) => {
          const lat = position.coords.latitude,
            lng = position.coords.longitude,
            geo = new qq.maps.Geolocation('QAWBZ-S2MWR-U5OWI-WZBUC-UXDSZ-AAFRJ', '获取位置信息');
          geo.getIpLocation(this.getIpLocationSuccess, this.getIpLocationErr, options);
        },
        (err) => {
          if (err.code === 1) {
            uni.showModal({
              title: '获取定位权限失败',
              content: '你拒绝了位置授权服务。请允许当前页面获取定位授权,后刷新页面。'
            });
          } else {
            uni.showModal({
              title: '获取定位权限失败',
              content: '请确定手机定位已打开,并且当前浏览器允许获取定位,都开启后请刷新页面。'
            });
          }
          uni.hideLoading();
        }
      );
    },
    getIpLocationSuccess(position) {
      uni.showToast({
        title: '定位成功!',
        duration: 1000
      });
      this.positionInfo = position;
      uni.hideLoading();
    },
    getIpLocationErr() {
      uni.showToast({
        title: '获取位置失败!',
        duration: 2000
      });
      uni.hideLoading();
    }
  }
};
</script>

效果如上一样,只是区别于当前是通过ip定位的。

 

实时监听当前位置:

<!-- 监听位置 -->
<template>
  <view class="watch-position">
    <view class="watch-position-btn">
      <view class="btn" @click="watchPosition">开启监听</view>
      <view class="btn" @click="clearWatch">关闭监听</view>
    </view>
    <view class="watch-position-info" v-if="positionInfo.length">
      <view class="watch-position-info-title">位置信息:</view>
      <view class="watch-position-info-list">
        <view class="watch-position-info-list-item" v-for="(item, index) in positionInfo" :key="index">
          {{ `第${index + 1}次:` }}<br />{{ JSON.stringify(item) }}
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import '@/utils/geolocation.min.js';
export default {
  data() {
    return {
      positionInfo: [],
      geo: null,
      isWatch: false
    };
  },
  onl oad() {
    this._initPosition();
  },
  methods: {
    _initPosition() {
      if (origin.indexOf('https') === -1) {
        uni.showToast({
          title: '请在https环境中使用'
        });
        return;
      }
      if (!navigator || !navigator.geolocation) {
        uni.showToast({
          title: '地理位置服务不可用',
          duration: 2000
        });
        return;
      }
      uni.showLoading({
        title: '定位中...',
        mask: true
      });
      /** err 说明
				code 1  表示用户拒绝授权
				code 3  未获取到地址信息,可能是设备没有开启定位服务或者系统没有给浏览器定位权限
			**/
      navigator.geolocation.getCurrentPosition(
        (position) => {
          const lat = position.coords.latitude,
            lng = position.coords.longitude,
            geo = new qq.maps.Geolocation('QAWBZ-S2MWR-U5OWI-WZBUC-UXDSZ-AAFRJ', '获取位置信息');
          this.geo = geo;
          uni.hideLoading();
        },
        (err) => {
          if (err.code === 1) {
            uni.showModal({
              title: '获取定位权限失败',
              content: '你拒绝了位置授权服务。请允许当前页面获取定位授权,后刷新页面。'
            });
          } else {
            uni.showModal({
              title: '获取定位权限失败',
              content: '请确定手机定位已打开,并且当前浏览器允许获取定位,都开启后请刷新页面。'
            });
          }
          uni.hideLoading();
        }
      );
    },
    watchPosition() {
      const options = {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0
      };
      if (this.isWatch)
        return uni.showToast({
          title: '已开启持续监听,请勿重复开启'
        });
      if (this.geo) {
        this.isWatch = true;
        this.geo.watchPosition(this.watchPositionSuccess, this.watchPositionErr, options);
      } else {
        uni.showModal({
          title: '获取定位权限失败',
          content: '请确定手机定位已打开,并且当前浏览器允许获取定位,都开启后请刷新页面。'
        });
      }
    },
    watchPositionSuccess(position) {
      this.positionInfo.push(position);
    },
    watchPositionErr() {
      uni.showToast({
        title: '获取位置失败!'
      });
    },
    clearWatch() {
      if (!this.isWatch)
        return uni.showToast({
          title: '已关闭持续监听,请勿重复关闭'
        });
      this.isWatch = false;
      this.geo.clearWatch();
    }
  }
};
</script>
<style lang="scss" scoped>
.watch-position {
  min-height: 100vh;
  background-color: #ededed;

  &-info {
    padding: 30rpx;

    &-title {
      margin-bottom: 30rpx;
    }

    &-list {
      background: #fff;

      &-item {
        width: 100%;
        margin-bottom: 20rpx;
        word-break: break-all;
      }
    }
  }

  &-btn {
    margin: 0 auto 40rpx;
    text-align: center;
    padding-top: 40rpx;
  }
}

.btn {
  background-color: #4cd964;
  color: #ffffff;
  margin: 0 auto 30rpx;
  padding: 15rpx;
  border-radius: 10rpx;
  font-size: 26rpx;
  text-align: center;
  width: 40%;
}
</style>

效果:

 

 

 

 注:使用浏览器定位域名必须是https访问

 

标签:geolocation,return,定位,title,h5,position,uni,navigator
From: https://www.cnblogs.com/zaijin-yang/p/17306685.html

相关文章

  • Python中将CSV文件转换为H5AD文件
    将CSV文件转换为H5AD文件,可以按照以下步骤进行:使用pandas库将CSV文件读入到Python中,并将其转换为dataframe格式: importpandasaspddf=pd.read_csv('data.csv')使用anndata库将dataframe转换为AnnData对象: importanndataasadadata=ad.AnnData(df)将......
  • h5 - pc 使用 pdf.js 预览pdf -配合文件流实现 - 遇到的坑总结
    1.pdf.js下载看我这篇随笔【h5-使用pdf.js预览pdf-岑惜-博客园(cnblogs.com)】2.html调用页面的局部代码<body><divstyle="height:100vh;margin:0auto"><iframestyle="height:100%;width:100%;border:none"id="fvic"src="&......
  • HTML5地理定位 Geolocation API
    使用getCurrentPosition方法来取得用户当前的地理位置信息,该方法的定义如下所示。voidgetCurrentPosition(onSuccess,onError,options);第一个参数为获取当前地理位置信息成功时所执行的回调函数;第二个参数为获取当前地理位置信息失败时所执行的回调函数;第三个参数为一些可选属......
  • 使用navigator.userAgent 判断当前浏览器所处的环境
    https://blog.csdn.net/banana960531/article/details/86572475浏览器对于我们来说,可能是最熟悉的工具了。熟知的浏览器Firefox、Opera、Safari、IE、Chrome以外,据说世界上还有近百种浏览器。通常在开发的时候要做到兼容各种浏览器,因此提炼出判断浏览器类型及系统是很重要的。先......
  • H5 如何实现唤起 APP?
    1、不同平台的实现方式有些不同,一般常见的有这几种,分别是:URLScheme(通用)UniversalLink(iOS)AppLink、ChromeIntents(android)2、推荐使用:3、优缺点对比......
  • h5移动端应用实现类似原生页面切换效果
    1.原理将vue-router中的跳转方法重写并监听,根据不同的跳转类型加载不同的过渡动画。2.实现创建router-helper.js文件exportconstDirectionType={//进入动画In:'in',//退出动画Out:'out',/**不应用动画,用于处理IOS侧滑冲突*/None:''}//路由动画export......
  • 【实战】SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
    JavaDogChatv1.0.0基于SpringBoot+uniapp简单通讯聊天软件......
  • uniapp app和H5网页的通信 app嵌套H5通过webview
    app发送信息给H5这个很简单,只要在网址上面携带参数就可以上面的例子是在app里面通过webview来嵌套网页,通过src的地址,可以携带参数,这样打开网页通过网址就可以获得传过来......
  • h5支付 授权域名限制的解决方案
    解决微信公众对于授权域名数量限制问题这是公众号支付(jsapi)方式,h5支付也是大致如此根据环境区分开即可首先在platform端需要留出下单页面(submit),支付成功手动重定向回......
  • 微信小程序内嵌H5,发布后无法打开页面
    解决方法一、在微信公众平台,登录微信小程序的帐号。二、配置业务域名进入【开发-开发管理-开发设置-业务域名】中,开始配置业务域名(配置业务域名需小程序管理员扫码验证......