Найденное местоположение на карте листовки вызывает непреднамеренного слушателя

У меня есть карта листовки, в которой map.locate() можно вызвать двумя способами: 1. Кнопка местоположения Easybutton, 2. Обычный вызов каждую минуту с помощью setTimeout.

У каждого есть свой собственный слушатель locationfound, или, по крайней мере, я бы хотел, чтобы они были — вот в чем проблема: нажатие на кнопку easybutton вызывает как прослушиватель control._map.on('locationfound'..) easybutton, так и слушатель map.on('locationfound'..) внутри getLocation().

Обычный вызов getLocation() запускает только прослушиватель map.on('locationfound'..). Это как-то связано с масштабом? Как мне сделать так, чтобы easybutton запускал только предполагаемого прослушивателя, а вызов setTimeout для map.locate() запускал только прослушиватель в getLocation()?

  L.easyButton({
    position: easy_position,
    states:[
      {
        stateName: 'unloaded',
        icon: 'fa-location-arrow',
        title: 'load image',
        onClick: function(control){
          control.state("loading");
          control._map.on('locationfound', function(e){
            alert('location found - easybutton');
            this.setView(e.latlng,18); // go to current location
            control.state('loaded');
            setTimeout(function(){
              control.state('unloaded');
            }, 3000);
          });
          control._map.on('locationerror', function(){
            control.state('error');
            setTimeout(function(){
              control.state('unloaded');
            }, 3000);
          });
          control._map.locate();
          setTimeout(function(){
            control.state('unloaded');
          }, 10000);  // give it ten seconds to find the location
        }
      }, {
        stateName: 'loading',
        icon: 'fa-spinner fa-spin'
      }, {
        stateName: 'loaded',
        icon: 'fa-thumbs-up'
      }, {
        stateName: 'error',
        icon: 'fa-frown-o',
        title: 'location not found'
      }
    ]
  }).addTo(map);

  function updateLocation() {
    getLocation(false);
    setTimeout(updateLocation, 60000);
  }

  getLocation = function(goToLocation) {
    map.on('locationfound', function(e) {
      alert('location found - getLocation()');
      var lat = e.latitude;
      var lng = e.longitude;
      if (goToLocation) {
        pan_to(lat,lng,0.5);
      }
    });
    map.on('locationerror', function(e) {
      console.info(e);
    });
    map.locate({
      setView: false,
      maxZoom: 16
    });
  }

Рассмотрите возможность прямого использования API геолокации браузера. См. developer.mozilla.org/en-US/docs/Web/API/Geolocation_API/…

IvanSanchez 09.05.2022 21:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
20
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете смягчить свою проблему, используя map.once() метод для присоединения ваших прослушивателей событий (как в вашем обычном процессе, так и в вашей кнопке), чтобы они удалялись после однократного срабатывания:

Behaves as on(…), except the listener will only get fired once and then removed.

Есть еще некоторые временные ситуации, когда оба слушателя могут быть запущены одновременно: если ваша кнопка нажата, когда ваш обычный процесс инициировал местоположение, но результат еще не получен, или наоборот.

К сожалению, Leaflet не различает вызовы метода map.locate(). Отсюда предложение @IvanSanchez напрямую использовать API браузера.

Вы можете устранить эти переходные ситуации, управляя флагом/мьютексом всякий раз, когда вы запускаете местоположение, а не выполняете другой или откладываете его, если ваш мьютекс заблокирован.

Подходы map.once() и flag кажутся вполне удовлетворительными. Мне было интересно, может ли быть более элегантное решение, связанное с областями. Что касается решения API браузера - я не вижу, как это меняет фундаментальную проблему? Что можно сделать с API браузера, чего нельзя сделать с помощью листовки?

Bazley 10.05.2022 16:00

Более креативное решение, которое, можно сказать, ближе к использованию прицелов, может состоять в том, чтобы использовать фиктивную карту только для другого места.

ghybs 10.05.2022 19:08

С API браузера вы указываете действие непосредственно как обратный вызов, поэтому вы также можете сказать, что он использует области. Тогда как с Листовкой нужно проходить события, а информации по разным источникам нет.

ghybs 10.05.2022 19:11

Другие вопросы по теме