经纬志
首页 / Leaflet / API 文档

DomEvent

先看结论

原生事件的绑定与拦截工具。自定义控件、覆盖物要自己处理点击与滚轮时,用这一套而不是 addEventListener。

最后验证 2026-11-03 · Leaflet 1.9.4 · 更新 2026-10-29 · 引用本文
L.DomEvent.on(el, types, fn, context?) → this

types 用空格分隔多个事件,例如 'click dblclick';context 决定回调里的 this。

方法

方法说明
on(el, types, fn, context?)绑定事件,别名 addListener
off(el, types, fn?, context?)解绑,别名 removeListener;省略 fn 时清掉该类型的全部回调
stopPropagation(e)阻止事件继续冒泡
preventDefault(e)阻止浏览器默认行为
stop(e)同时做上面两件事
disableScrollPropagation(el)拦截滚轮冒泡,地图不会因滚轮而缩放
disableClickPropagation(el)拦截点击、双击与右键的冒泡
getMousePosition(e, container?)相对容器左上角的像素坐标,返回 Point
getWheelDelta(e)把各浏览器不同的滚轮增量归一到统一方向与量级
isExternalTarget(el, e)判断事件目标是否在元素之外,用于「点外面关闭」
fakeStop(e)标记事件已被处理,让后续 skipped 判断生效
skipped(e)配合 fakeStop,判断事件是否已被同一个处理器跳过
getPropagationPath(e)返回事件传播路径数组,优先使用 composedPath()

控件里的点击与滚轮

控件容器在地图上方,不拦截的话,点按钮会同时触发地图点击,滚轮也会带着地图缩放。

var ZoomBox = L.Control.extend({
  onAdd: function () {
    var box = L.DomUtil.create('div', 'zoom-box');
    box.innerHTML =
      '<button data-step="1">放大</button>' +
      '<button data-step="-1">缩小</button>';

    L.DomEvent.disableClickPropagation(box);
    L.DomEvent.disableScrollPropagation(box);

    L.DomEvent.on(box, 'click', function (e) {
      var step = Number(e.target.getAttribute('data-step'));
      if (!step) { return; }
      map.setZoom(map.getZoom() + step);
    });

    return box;
  }
});

map.addControl(new ZoomBox({ position: 'topright' }));

读取容器内的鼠标位置

画布上的像素拾取要用相对容器的坐标,页面坐标会随滚动与布局变化。 第二个参数给容器元素时按容器计算,省略时按 document 计算。

L.DomEvent.on(map.getContainer(), 'mousemove', function (e) {
  var p = L.DomEvent.getMousePosition(e, map.getContainer());
  hoverLabel.textContent = Math.round(p.x) + ', ' + Math.round(p.y);
});

点击外部关闭

function closeOnOutsideClick(panel) {
  function handler(e) {
    if (!L.DomEvent.isExternalTarget(panel, e)) { return; }
    map.removeControl(panelControl);
    L.DomEvent.off(document, 'click', handler);
  }

  L.DomEvent.on(document, 'click', handler);
}

别对地图容器用 stopPropagation。 Leaflet 的拖动、缩放与点击判定都挂在容器上,拦掉冒泡会让这些交互失效。 只需要阻止控件自己的事件外泄,拦控件容器即可。

与 Evented 的分工

DomEvent 处理浏览器原生事件,L.Evented 处理 Leaflet 自己的事件对象。 图层上的 map.on('click', fn) 走后者,回调拿到的是带 latlng 与 layerPoint 的包装对象, 而不是原生 MouseEvent。

引用本文

经纬志(2026)。《DomEvent》。https://www.jingweizhi.com/leaflet/api/dom-event.html(访问日期 2026-11-03)。