Как программно закрыть все всплывающие окна в mapbox gl?

Итак, я знаю, что у нас есть Marker.togglePopup() в Mapbox GL Api. Но можем ли мы программно закрыть все всплывающие окна?


person Yahor Vaziyanau    schedule 29.11.2016    source источник
comment
То же, что stackoverflow.com/questions/40849927/, это предполагает, что всплывающие окна привязаны к некоторым маркерам. Я использую всплывающие окна на карте, которые не привязаны ни к какому маркеру (как в примере mapbox.com/mapbox-gl-js/example/popup). Есть ли способ получить все открытые всплывающие окна с карты?   -  person Suma    schedule 03.05.2018


Ответы (4)


Вот пример: https://jsfiddle.net/kmandov/eozdazdr/
Нажмите кнопку кнопки в правом верхнем углу, чтобы открыть/закрыть всплывающее окно.

Учитывая, что у вас есть всплывающее окно и маркер:

var popup = new mapboxgl.Popup({offset:[0, -30]})
    .setText('Construction on the Washington Monument began in 1848.');

new mapboxgl.Marker(el, {offset:[-25, -25]})
    .setLngLat(monument)
    .setPopup(popup)
    .addTo(map);

Вы можете закрыть всплывающее окно, вызвав:

popup.remove();

или вы можете открыть его, позвонив:

popup.addTo(map);

Как видно из источника маркера, togglePopup использует эти два внутренних метода:

togglePopup() {
    var popup = this._popup;

    if (!popup) return;
    else if (popup.isOpen()) popup.remove();
    else popup.addTo(this._map);
}
person kmandov    schedule 29.11.2016
comment
Это полезно для закрытия определенного всплывающего окна, но не решает проблему всех всплывающих окон на карте, поскольку предполагает, что у вас есть ссылка на popup для вызова popup.remove(). Есть ли способ получить доступ ко всем всплывающим окнам на карте? - person Stephen Lead; 17.04.2020
comment
@StephenLead см. мой ответ о том, как закрыть все всплывающие окна, независимо от того, как они были созданы. - person squarecandy; 21.07.2020

Принятый ответ не относился к моему варианту использования (я не использовал маркер). Мне удалось найти другое решение, используя встроенный в mapbox рабочий процесс обработки событий. Надеюсь, это поможет кому-то другому.

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

Учитывая, что у вас есть всплывающее окно:

// Create popup and add it to the map
const popup = new mapboxgl.Popup({ offset: 37, anchor: 'bottom' }).setDOMContent('<h5>Hello</h5>').setLngLat(feature.geometry.coordinates).addTo(map);

// Add a custom event listener to the map
map.on('closeAllPopups', () => {
  popup.remove();
});

Если вы хотите закрыть все всплывающие окна, запустите событие:

map.fire('closeAllPopups');
person Dan Sterrett    schedule 21.01.2020
comment
По сути, вы сохраняете всплывающее окно в переменной и получаете к нему доступ через это. Хотелось бы, чтобы был способ получить к нему доступ с самой карты. Нравится, map.getMarker(id) - person Pankaj; 29.01.2021

Mapbox автоматически использует класс .mapboxgl-popup для всплывающего окна. Вы также можете добавить дополнительные классы с помощью options.className.

Итак, если у вас есть jQuery, просто выполните:

$('.mapboxgl-popup').remove();

Или обычный javascript:

const popup = document.getElementsByClassName('mapboxgl-popup');
if ( popup.length ) {
    popup[0].remove();
}

Я почти уверен, что вы можете предположить, что открыто только одно всплывающее окно. Поведение по умолчанию, по-видимому, заключается в том, что если один из них открыт и щелкнут второй элемент, первое всплывающее окно полностью удаляется из DOM при открытии второго. Если ваше приложение каким-то образом допускает несколько открытых всплывающих окон, вам нужно будет пройти и удалить каждое из них с помощью простого js, а не использовать только первый элемент.

person squarecandy    schedule 21.07.2020
comment
Небезопасно предполагать, что есть только одно всплывающее окно. Вы можете установить {closeOnClick: false} и иметь столько всплывающих окон, сколько поместится на экране. - person blindguy; 15.05.2021
comment
Хорошо, круто, хороший звонок, но основная предпосылка все еще должна работать. Приведенный выше jQuery должен просто работать, а простые js вам придется перебирать от popup до remove() каждого. - person squarecandy; 15.05.2021

Я знаю, что это старый вопрос, но недавно я работал над Mapbox. Начиная с mapbox-gl v2.3, mapboxgl.Popup имеет свойство closeOnClick, где, если установлено значение true, всплывающее окно исчезает, когда вы щелкаете вне всплывающего окна.

let popup = new mapboxgl.Popup({
  anchor: "top",
  closeOnClick: true,
});

map.on(
  "click",
  "location",
  (e) => {
    map.getCanvas().style.cursor = "pointer";

    let coordinates = e.features[0].geometry.coordinates.slice();

    popup
      .setLngLat(coordinates)
      .setHTML("what I want to display")
      .addTo(map);
  }
);

Кроме того, вы можете показать всплывающее окно при входе мыши вместо щелчка и добавить событие mouseleave, чтобы удалить всплывающее окно:

  map.on(
  "mouseleave",
  "location",
  () => {
    map.getCanvas().style.cursor = "";
     popup.remove();
  }
);
person m007    schedule 01.07.2021