Commandes de fenêtre contextuelle et événements
Cliquez sur une ville : sa fenêtre contextuelle propose Add to shortlist, une action ajoutée par cette page. La choisir déclenche un événement qui transporte l'entité, et la page en tire une liste de présélection. Le journal en dessous affiche les événements à mesure qu'ils arrivent ; remarquez la reason de chacun.
Points à remarquer
- Seuls un id et un titre en texte brut entrent dans la carte, jamais de HTML ni de script.
- Rien n'est envoyé tant que vous ne vous êtes pas abonné : une incorporation qui se contente d'afficher une carte ne coûte donc rien de plus.
- Chaque événement d'état porte une
reason:user,command,bookmark,tour,sceneouload.
Le code
La page complète. Remplacez l'identifiant de publication par le vôtre, et demandez à l'auteur de la carte d'ajouter votre site à ses origines autorisées.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Popup commands and events - Icon Map Embed API</title>
<link rel="stylesheet" href="https://www.icon-map.com/embed-examples/examples.css"> <!-- demo styling only -->
</head>
<body>
<div class="ex-main">
<div class="ex-side">
<h2>Shortlist</h2>
<ul class="ex-list" id="shortlist"><li style="cursor:default"><span>Click a city, then "Add to shortlist".</span></li></ul>
<h2>Events</h2>
<pre class="ex-log" id="log"></pre>
</div>
<div id="map"></div>
</div>
<script src="https://www.icon-map.com/js/iconmap-embed/2/iconmap-embed.umd.min.js"></script>
<script>
const el = document.getElementById("map");
const map = IconMapEmbed.embed(el, {
publishId: "pub_...",
// The map is a globe: let this page's own background show in the space around it.
background: "transparent",
chrome: { layerControl: false, bookmarksBar: false, legend: false, tourTransport: false },
visibility: { visuals: { "chart-continent": false, "slicer-continent": false, "slicer-size": false, "slicer-capital": false } },
});
map.ready.catch((error) => console.error(error.code, error.message));
// --- your own action in the feature popup -------------------------------------------
// Only an id and a plain-text title cross into the map - never HTML or script.
map.addMenuCommand({ id: "shortlist", title: "Add to shortlist", layerIds: ["cities"] });
const shortlist = new Map();
map.on("menuCommandTriggered", ({ commandId, featureKey, fields }) => {
if (commandId !== "shortlist") return;
shortlist.set(featureKey, fields);
const host = document.getElementById("shortlist");
host.textContent = "";
for (const [key, f] of shortlist) {
const row = document.createElement("li");
row.innerHTML = `<span>${f.city}</span><span>${(Number(f.population) / 1e6).toFixed(1)}M</span>`;
row.onclick = () => map.selectByKey({ layerId: "cities", keys: [key], zoomTo: true });
host.append(row);
}
// Paint the whole shortlist without disturbing what the reader selected.
map.highlight({ layerId: "cities", keys: [...shortlist.keys()] });
});
// --- every event carries a reason, so a two-way sync can ignore its own echo --------
const log = (name, text) => {
const line = document.createElement("div");
line.innerHTML = `<b>${name}</b> ${text}`;
document.getElementById("log").prepend(line);
};
map.on("viewChanged", (v) => log("viewChanged", `${v.reason} - z${v.zoom.toFixed(1)}`));
map.on("featureClick", (f) => log("featureClick", f ? `${f.layerId}: ${f.fields.city ?? f.fields.country}` : "empty map"));
map.on("selectionChanged", (s) => log("selectionChanged", `${s.reason} - ${Object.values(s.selection).flat().length} selected`));
map.on("visibilityChanged", (v) => log("visibilityChanged", v.reason));
map.on("rendered", (r) => log("rendered", `first frame in ${r.durationMs} ms`));
</script>
</body>
</html>