如何在 mapbox gl 中以编程方式关闭所有弹出窗口?
How to close all popups programmatically in mapbox gl?
所以,我知道我们在 Mapbox GL API 中有 Marker.togglePopup()
。
但是我们可以通过编程方式关闭所有弹出窗口吗?
这是一个例子:https://jsfiddle.net/kmandov/eozdazdr/
单击右上角的按钮 open/close 弹出窗口。
假设您有一个弹出窗口和一个标记:
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);
如您在 Marker source 中所见,togglePopup
在内部使用了这两种方法:
togglePopup() {
var popup = this._popup;
if (!popup) return;
else if (popup.isOpen()) popup.remove();
else popup.addTo(this._map);
}
接受的答案不适用于我的用例(我没有使用标记)。通过利用 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');
Mapbox 自动使用 class .mapboxgl-popup
作为弹出窗口。您还可以使用 options.className
.
添加额外的 classes
因此,如果您有 jQuery 可用,只需执行:
$('.mapboxgl-popup').remove();
或普通 javascript:
const popup = document.getElementsByClassName('mapboxgl-popup');
if ( popup.length ) {
popup[0].remove();
}
我很确定您可以假设只有一个弹出窗口打开。默认行为似乎是,如果打开一个并单击第二个项目,则当第二个打开时,第一个弹出窗口将从 DOM 中完全删除。如果您的应用程序以某种方式允许多个打开的弹出窗口,您将需要循环遍历并使用纯 js 删除每个弹出窗口,而不是仅使用第一个项目。
我知道这是一个老问题,但我最近在研究 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);
}
);
或者,您可以在“mouseenter”而不是“click”上显示弹出窗口,并添加“mouseleave”事件以删除弹出窗口:
map.on(
"mouseleave",
"location",
() => {
map.getCanvas().style.cursor = "";
popup.remove();
}
);
用 React.StrictMode
和 closeOnClick={false}
包装你的弹出窗口。
const [popup, setPopup] = useState<boolean>(false);
...
{popup && (
<React.StrictMode>
<Popup longitude={52.001126260374704} latitude={34.906269171550214}
anchor="bottom"
onClose={() => {
setPopup(false)
}}
closeOnClick={false}
>
You are here
</Popup>
</React.StrictMode>
)}
所以,我知道我们在 Mapbox GL API 中有 Marker.togglePopup()
。
但是我们可以通过编程方式关闭所有弹出窗口吗?
这是一个例子:https://jsfiddle.net/kmandov/eozdazdr/
单击右上角的按钮 open/close 弹出窗口。
假设您有一个弹出窗口和一个标记:
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);
如您在 Marker source 中所见,togglePopup
在内部使用了这两种方法:
togglePopup() {
var popup = this._popup;
if (!popup) return;
else if (popup.isOpen()) popup.remove();
else popup.addTo(this._map);
}
接受的答案不适用于我的用例(我没有使用标记)。通过利用 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');
Mapbox 自动使用 class .mapboxgl-popup
作为弹出窗口。您还可以使用 options.className
.
因此,如果您有 jQuery 可用,只需执行:
$('.mapboxgl-popup').remove();
或普通 javascript:
const popup = document.getElementsByClassName('mapboxgl-popup');
if ( popup.length ) {
popup[0].remove();
}
我很确定您可以假设只有一个弹出窗口打开。默认行为似乎是,如果打开一个并单击第二个项目,则当第二个打开时,第一个弹出窗口将从 DOM 中完全删除。如果您的应用程序以某种方式允许多个打开的弹出窗口,您将需要循环遍历并使用纯 js 删除每个弹出窗口,而不是仅使用第一个项目。
我知道这是一个老问题,但我最近在研究 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);
}
);
或者,您可以在“mouseenter”而不是“click”上显示弹出窗口,并添加“mouseleave”事件以删除弹出窗口:
map.on(
"mouseleave",
"location",
() => {
map.getCanvas().style.cursor = "";
popup.remove();
}
);
用 React.StrictMode
和 closeOnClick={false}
包装你的弹出窗口。
const [popup, setPopup] = useState<boolean>(false);
...
{popup && (
<React.StrictMode>
<Popup longitude={52.001126260374704} latitude={34.906269171550214}
anchor="bottom"
onClose={() => {
setPopup(false)
}}
closeOnClick={false}
>
You are here
</Popup>
</React.StrictMode>
)}