唯杰地图 logo唯杰地图
VJMAP
EN

marker-binding

vjmap/references/popup/marker-binding.md 3.2 KB111 行
原文

本文回答:Popup 与 Marker 绑定 —— setPopup / togglePopup / getPopup / 自动联动位置。

一、setPopup 一次设定

const popup = new vjmap.Popup({ offset: [0, -40] })
  .setHTML("<b>站点 A</b>");

new vjmap.Marker()
  .setLngLat([lng, lat])
  .setPopup(popup)
  .addTo(map);

点 Marker 打开 Popup。⚠️ 默认 closeOnClick: true 时再点 Marker 会先关后开(popup 在 preclick 关闭,Marker 随后在 click 里 toggle 又打开,关不掉);要开 / 关切换用 new vjmap.Popup({ closeOnClick: false })。

二、解绑 / 替换

marker.setPopup(undefined);        // 解绑
marker.setPopup(newPopup);         // 换新 popup

三、手动 toggle / 开关

marker.togglePopup();              // 切换
marker.getPopup()?.isOpen();       // 读状态

四、动态更新 Popup 内容

const popup = new vjmap.Popup().setHTML("loading...");
marker.setPopup(popup);

async function refresh() {
  const data = await fetchSiteData();
  popup.setHTML(`<b>${data.name}</b><br/>温度:${data.temp}℃`);
}

五、悬停打开,离开关闭

const popup = new vjmap.Popup({ closeButton: false, offset: [0, -40] })
  .setHTML("hover me");

const el = marker.getElement();
el.addEventListener("mouseenter", () => {
  if (!popup.isOpen()) popup.setLngLat(marker.getLngLat()).addTo(map);
});
el.addEventListener("mouseleave", () => popup.remove());

六、Marker 移动时 Popup 跟随

marker 绑定 popup 后,marker 移动时 popup 位置自动跟随:

marker.setLngLat([newLng, newLat]);  // popup 自动跟着

不绑定的独立 Popup 需要手动:

popup.setLngLat([newLng, newLat]);

七、多个 Marker 共享一个 Popup

const popup = new vjmap.Popup({ closeButton: false });

markers.forEach(m => {
  m.getElement().addEventListener("click", e => {
    popup.setLngLat(m.getLngLat()).setHTML(m.data.name).addTo(map);
  });
});

好处:少 DOM 节点、少内存。

八、绑定后修改 Popup Offset

marker.setPopup(new vjmap.Popup({ offset: [0, -60] }).setHTML("..."));

注意:默认水滴 Marker 绑 popup 时,vjmap 自动把 popup 的默认 offset 设为 {bottom:[0,-38.1],...}(38.1px ≈ 水滴高 41px),已对齐底端;自定义 element 时该默认值改为 this._offset,要手动对齐。

九、绑定 popup 和 dragend

const popup = new vjmap.Popup().setHTML("拖我");
marker.setPopup(popup);
marker.togglePopup();           // 预先打开

marker.on("drag", () => {
  const ll = marker.getLngLat();
  popup.setHTML(`(${ll.lng.toFixed(4)}, ${ll.lat.toFixed(4)})`);
});

十、常见坑

  1. setPopup 后不自动打开:需要 togglePopup 或点击 Marker。
  2. Popup 离 Marker 位置偏:检查 marker 的 anchor 和 popup 的 offset 是否对齐。
  3. marker 被 hide 时 popup 还在:hide marker 不自动关 popup;自己 popup.remove()。
  4. Popup 点击关闭但 Marker 仍选中状态:popup 关不影响 marker;可监听 popup.on('close', ...) 更新业务状态。