Popup
Popups are used to display information on the map, usually used in conjunction with click or hover events. The SDK provides flexible popup functionality, supporting HTML content, custom styles, and multiple positioning methods.
Basic Usage
Create Popup
javascript
// Create popup instance
const popup = new navMap.Popup({
closeButton: true, // Show close button
closeOnClick: true, // Close on map click
anchor: "bottom", // Anchor position
offset: [0, -10], // Offset
className: "custom-popup", // Custom CSS class
});
// Set position and content
popup.setLngLat([116.3974, 39.9093])
.setHTML("<h3>Beijing</h3><p>Capital of China</p>")
.addTo(sdk.map);Set HTML Content
javascript
// Set simple HTML
popup.setHTML("<h3>Title</h3><p>Content</p>");
// Set complex HTML
popup.setHTML(`
<div class="popup-content">
<h3>${feature.properties.name}</h3>
<p>Coordinates: ${coordinates.join(", ")}</p>
<button onclick="doSomething()">Action</button>
</div>
`);Set Text Content
javascript
// Set plain text
popup.setText("This is text content");Remove Popup
javascript
// Remove popup
popup.remove();
// Or
popup.removeFrom(sdk.map);Show Popup on Click
Basic Click Popup
javascript
sdk.on("click", (e) => {
const popup = new navMap.Popup()
.setLngLat(e.lngLat)
.setHTML("<h3>Click Position</h3>")
.addTo(sdk.map);
});Show Popup on Feature Click
javascript
sdk.on("click", "airport", (e) => {
const feature = e.features[0];
const popup = new navMap.Popup()
.setLngLat(e.lngLat)
.setHTML(`<h3>${feature.properties.name}</h3>`)
.addTo(sdk.map);
});Using ClickManager
javascript
// Use ClickManager to simplify click popup
sdk.clickObj.clickPopup(
"airport", // Layer ID
(feature) => { // HTML generation function
return `<h3>${feature.properties.name}</h3>
<p>Type: ${feature.properties.type}</p>`;
},
{ // Popup options
anchor: "bottom",
closeButton: true,
}
);Async Content Loading
javascript
// Support async content loading
sdk.clickObj.clickPopup(
"airport",
async (feature) => {
// Async fetch data
const data = await fetch(`/api/airport/${feature.properties.id}`)
.then(r => r.json());
return `<h3>${data.name}</h3>
<p>Details: ${data.description}</p>`;
},
{
anchor: "bottom",
}
);Show Popup on Hover
Basic Hover Popup
javascript
sdk.on("mouseenter", "airport", (e) => {
const popup = new navMap.Popup({
closeButton: false, // Hover popups usually don't show close button
})
.setLngLat(e.lngLat)
.setHTML(`<h3>${e.features[0].properties.name}</h3>`)
.addTo(sdk.map);
});
sdk.on("mouseleave", "airport", () => {
popup.remove();
});Using HoverManager
javascript
// Use HoverManager to simplify hover popup
sdk.hover.hoverPopup(
"airport", // Layer ID
(feature) => { // HTML generation function
return `<div>${feature.properties.name}</div>`;
},
{ // Popup options
anchor: "top",
closeButton: false,
}
);Async Content Loading
javascript
// Support async content loading
sdk.hover.hoverPopup(
"airport",
async (feature) => {
const data = await fetch(`/api/airport/${feature.properties.id}`)
.then(r => r.json());
return `<div>${data.name}</div>`;
},
{
anchor: "top",
}
);Popup Options
Anchor Position
javascript
const popup = new navMap.Popup({
anchor: "bottom", // Options:
// "center" | "top" | "bottom" | "left" | "right" |
// "top-left" | "top-right" | "bottom-left" | "bottom-right"
});Offset
javascript
const popup = new navMap.Popup({
offset: [0, -10], // [x, y] pixel offset
});
// Or use object
const popup = new navMap.Popup({
offset: {
"bottom": [0, -10],
"top": [0, 10],
"left": [-10, 0],
"right": [10, 0],
},
});Max Width
javascript
const popup = new navMap.Popup()
.setMaxWidth("300px"); // Set max widthCustom CSS Class
javascript
const popup = new navMap.Popup({
className: "custom-popup",
});
// CSS
.custom-popup {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}Popup Events
Listen to Popup Events
javascript
const popup = new navMap.Popup();
// Open event
popup.on("open", () => {
console.log("Popup opened");
});
// Close event
popup.on("close", () => {
console.log("Popup closed");
});
popup.setLngLat([116.3974, 39.9093])
.setHTML("<h3>Content</h3>")
.addTo(sdk.map);Dynamic Content Updates
Update Position
javascript
// Update popup position
popup.setLngLat([121.4737, 31.2304]);Update Content
javascript
// Update HTML content
popup.setHTML("<h3>New Content</h3>");
// Update text content
popup.setText("New text");Track Map Movement
javascript
// Popup follows feature movement
sdk.on("move", () => {
if (popup.isOpen()) {
const newPosition = calculateNewPosition();
popup.setLngLat(newPosition);
}
});Multiple Popup Management
Singleton Pattern
javascript
// Ensure only one popup at a time
let currentPopup = null;
sdk.on("click", "airport", (e) => {
// Close previous popup
if (currentPopup) {
currentPopup.remove();
}
// Create new popup
currentPopup = new navMap.Popup()
.setLngLat(e.lngLat)
.setHTML(`<h3>${e.features[0].properties.name}</h3>`)
.addTo(sdk.map);
});Popup Manager
javascript
class PopupManager {
constructor(map) {
this.map = map;
this.popups = new Map();
}
show(id, lngLat, html) {
// Close previous popup
this.hide(id);
// Create new popup
const popup = new navMap.Popup()
.setLngLat(lngLat)
.setHTML(html)
.addTo(this.map);
this.popups.set(id, popup);
}
hide(id) {
const popup = this.popups.get(id);
if (popup) {
popup.remove();
this.popups.delete(id);
}
}
hideAll() {
this.popups.forEach(popup => popup.remove());
this.popups.clear();
}
}
// Usage
const popupManager = new PopupManager(sdk.map);
popupManager.show("airport-1", [116.3974, 39.9093], "<h3>Beijing</h3>");Style Customization
Custom Styles
css
/* Global popup styles */
.maplibregl-popup {
font-family: Arial, sans-serif;
}
.maplibregl-popup-content {
padding: 15px;
border-radius: 8px;
}
.maplibregl-popup-close-button {
font-size: 18px;
color: #333;
}
/* Custom class styles */
.custom-popup .maplibregl-popup-content {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}Responsive Design
css
@media (max-width: 768px) {
.maplibregl-popup-content {
max-width: 90vw;
font-size: 14px;
}
}Complete Example
javascript
let sdk;
let currentPopup = null;
async function initMap() {
sdk = new navMap.MapSDK({
container: "map",
center: [116.39, 39.9],
zoom: 10,
});
sdk.on("loadComplete", () => {
setupPopups();
});
}
function setupPopups() {
// 1. Show popup on click
sdk.on("click", "airport", (e) => {
const feature = e.features[0];
// Close previous popup
if (currentPopup) {
currentPopup.remove();
}
// Create new popup
currentPopup = new navMap.Popup({
closeButton: true,
closeOnClick: true,
anchor: "bottom",
className: "airport-popup",
})
.setLngLat(e.lngLat)
.setHTML(`
<div class="popup-content">
<h3>${feature.properties.name}</h3>
<p>Type: ${feature.properties.type}</p>
<p>Coordinates: ${e.lngLat.lng.toFixed(4)}, ${e.lngLat.lat.toFixed(4)}</p>
</div>
`)
.addTo(sdk.map);
// Listen to popup events
currentPopup.on("close", () => {
console.log("Popup closed");
});
});
// 2. Use ClickManager
sdk.clickObj.clickPopup(
"airline",
async (feature) => {
// Async load data
const data = await fetch(`/api/airline/${feature.properties.id}`)
.then(r => r.json());
return `
<h3>${data.name}</h3>
<p>${data.description}</p>
`;
},
{
anchor: "bottom",
closeButton: true,
maxWidth: "300px",
}
);
// 3. Use HoverManager
sdk.hover.hoverPopup(
"airport",
(feature) => {
return `<div>${feature.properties.name}</div>`;
},
{
anchor: "top",
closeButton: false,
}
);
}
initMap();Notes
- Memory Management: Promptly remove unnecessary popups to avoid memory leaks
- Event Cleanup: Remove popup event listeners before page unload
- Performance Optimization: Avoid creating popups in frequently triggered events
- Content Security: Pay attention to XSS protection when using
setHTML - Responsive Design: Consider popup display effects on mobile devices
