代码之家  ›  专栏  ›  技术社区  ›  Jordy

如果用户在3秒后没有做出决定,如何检测用户位置权限的超时?

  •  0
  • Jordy  · 技术社区  · 2 年前

    我想在用户对位置的权限没有做出决定后执行任务。我尝试了以下方法:

    navigator.geolocation.getCurrentPosition((pos) => {
        let lat = pos.coords.latitude;
        let long = pos.coords.longitude;
        console.log(lat, long);
        console.log("User granted permission");
    }, (error) => {
        console.error(error);
        console.error("User didn't grant permission");
    }, {
        timeout: 3000,
        maximumAge: 3000,
        enableHighAccuracy: true
    });

    我已经设定好了 timeout maximumAge 属性到 3000 女士,但它已经不起作用了。只有当用户关闭权限弹出窗口时,才会触发错误。我如何检测用户在3秒后是否没有做出决定?非常感谢。


    脚本:

    1. 网站由用户打开->出现位置警报->用户未点击 Allow Block 持续时间长达3秒-> Save dummy data location to database .
    2. 网站由用户打开->出现位置警报->用户点击 允许 3秒之前-> Save user data location to database .
    3. 网站由用户打开->出现位置警报->用户点击 阻止 3秒之前-> 将虚拟数据位置保存到数据库 .

    限制:

    • 每个场景都不应该执行双重操作。
    • 如果用户曾经 允许 阻止 ,然后执行适当的操作。
    1 回复  |  直到 1 年前
        1
  •  3
  •   Prerak Patel    1 年前

    我认为在这种情况下,我们的地理定位API的前景将是一个很好的解决方案。

    const getPosition = function () {
      // this will return a new Promise which will then give us Position when it's fulfilled
      return new Promise(function (resolve, reject) {
        // solution-1: more simplified version
        navigator.geolocation.getCurrentPosition(resolve, reject);
    
        // solution-2:
        // navigator.geolocation.getCurrentPosition(
        //   position => resolve(position),
        //   err => reject(err)
        // );
      });
    };
    
    // Simple Timeout function
    const timeout = function (sec) {
      // Here we just want to reject our promise so we can neglect resolve by replacing it with '_'
      return new Promise(function (_, reject) {
        setTimeout(function () {
          reject(new Error('Request took too long!'));
        }, sec * 1000);
      });
    };
    
    
    // Promise.race accepts array of Promise and return the first fulfilled promise
    Promise.race([getPosition(), timeout(3)])
      .then(pos => {
         let lat = pos.coords.latitude;
         let long = pos.coords.longitude;
         console.log(lat, long);
         console.log('User granted permission');
      })
      .catch(error => {
         console.error(error);
         console.error("User didn't grant permission");
      });

    阅读更多

        2
  •  3
  •   offscriptdev    1 年前

    需要明确的是,如果用户没有单击其中一个提示选项,听起来你想做的是在3秒后关闭导航器地理位置提示。 这是不可能的 为什么?

    导航器地理位置提示由浏览器控制,它不公开任何关闭弹出窗口的方法。

    getCurrentPosition() 只有成功和错误处理程序,以及maximumAge、timeout和enableHighAccuracy选项。timeout选项有点误导,因为您可能会认为它是针对用户输入的超时。事实并非如此。超时是在单击accept后通过地理定位api发出的网络请求。

    navigator.geolocation 只公开了三个方法:clearWatch()、getCurrentPosition()和watchPosition()。这些方法都不能中断getCurrentPosition()的调用。

    进一步阅读表明,最佳做法是制作一个软提示,请求用户允许进行地理定位请求,理想情况下只有在某种用户输入之后(人们往往不喜欢在加载时弹出提示):

    如果你仍然想在加载时显示地理位置提示,如果用户没有用setTimeout()在提示上单击接受或拒绝,并且用clearTimeout()清除成功或错误,那么没有什么能阻止你执行其他操作。你只是不能用JS作为这些操作之一来关闭提示符。

        3
  •  0
  •   Kirill    2 年前

    您可以添加 setTimeout 之前打电话 获取当前位置 如果用户执行了某些操作,则清除timeoutID:

    var timeoutID = window.setTimeout(() => {
        console.log('user makes no decision');
        // do 1
    }, 3000);
    
    navigator.geolocation.getCurrentPosition((pos) => {
        timeoutID && window.clearTimeout(timeoutID);
        // do 2
    }, (error) => {
        timeoutID && window.clearTimeout(timeoutID);
        // do 3
    }, {});