Atlaslog
Atlaslog / Examples / Leaflet / Zoom Slider
Leaflet · Runnable Example

Zoom Slider

Runnable Leaflet example: Zoom Slider. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.

Open standalone → Chinese notes All Leaflet examples
/demos/leaflet-zoom-slider.htmlLIVE
single HTML file · CDN dependencies onlyinterface may contain Chinese labels

Source

demos/leaflet-zoom-slider.html
<!--
  示例:缩放滑块
  要点:L.Control.extend 自定义控件、range 滑块与 setZoom 双向同步、控件内事件阻断
  依赖:Leaflet 1.9.4 · jsDelivr CDN
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="robots" content="noindex,follow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>缩放滑块</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.css">
<style>
  html,body{height:100%;margin:0}
  body{font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif}
  #map{position:absolute;inset:0}
  .zoom-slider{
    background:#fff;border-radius:6px;padding:8px 10px;
    box-shadow:0 2px 10px rgba(0,0,0,.16);width:190px;
    font:12px/1.5 -apple-system,"Segoe UI","PingFang SC",sans-serif;color:#58606e;
  }
  .zoom-slider .row{display:flex;align-items:center;gap:8px}
  .zoom-slider .lbl{white-space:nowrap}
  .zoom-slider input[type=range]{flex:1;accent-color:#1f5fd0}
  .zoom-slider .val{font-variant-numeric:tabular-nums;color:#16181d;font-weight:600;
    min-width:26px;text-align:right}
  .zoom-slider .scale{display:flex;justify-content:space-between;font-size:10px;
    color:#9aa3b0;margin-top:2px}
  .zoom-slider button{font:inherit;font-size:11px;padding:2px 8px;margin-top:6px;
    border:1px solid #ccd1d9;border-radius:4px;background:#fff;cursor:pointer;color:#16181d}
  .zoom-slider button:hover{background:#eef0f3}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
(function () {
  'use strict';

  var map = L.map('map', {
    center: [39.907359, 116.391263],
    zoom: 11,
    zoomSnap: 1,
    minZoom: 4,
    maxZoom: 18
  });

  L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
    maxZoom: 19,
    attribution: 'Tiles © Esri'
  }).addTo(map);

  var ZoomSlider = L.Control.extend({
    options: { position: 'topright' },

    onAdd: function (map) {
      var box = L.DomUtil.create('div', 'zoom-slider leaflet-bar');
      box.innerHTML =
        '<div class="row">' +
          '<span class="lbl">缩放</span>' +
          '<input type="range" min="' + map.getMinZoom() + '" max="' + map.getMaxZoom() +
            '" step="1" value="' + map.getZoom() + '" aria-label="缩放级别">' +
          '<span class="val">' + map.getZoom() + '</span>' +
        '</div>' +
        '<div class="scale"><span>' + map.getMinZoom() + '</span><span>' + map.getMaxZoom() + '</span></div>' +
        '<button type="button" data-act="reset">回到 11 级</button>';

      var input = box.querySelector('input');
      var val = box.querySelector('.val');

      /* 控件里的鼠标与滚轮必须与地图隔离,否则拖动滑块会拖动地图 */
      L.DomEvent.disableClickPropagation(box);
      L.DomEvent.disableScrollPropagation(box);
      L.DomEvent.on(input, 'mousedown touchstart', L.DomEvent.stopPropagation);
      L.DomEvent.on(input, 'wheel', L.DomEvent.stopPropagation);

      input.addEventListener('input', function () {
        map.setZoom(Number(input.value));
      });

      box.querySelector('button').addEventListener('click', function () {
        map.setZoom(11);
      });

      this._input = input;
      this._val = val;
      this._sync = function () {
        var z = map.getZoom();
        if (Number(input.value) !== z) input.value = z;
        val.textContent = z;
      };
      map.on('zoomend', this._sync);

      return box;
    },

    onRemove: function (map) {
      map.off('zoomend', this._sync);
    }
  });

  new ZoomSlider().addTo(map);

  /* 缩放级别变化与视野中心一起显示,方便对照瓦片层级 */
  var status = L.control({ position: 'bottomleft' });
  status.onAdd = function () {
    var div = L.DomUtil.create('div', 'leaflet-bar');
    div.style.cssText = 'padding:5px 9px;background:#fff;font-size:12px;color:#16181d';
    this._div = div;
    return div;
  };
  status.addTo(map);

  function refresh() {
    var c = map.getCenter();
    status._div.textContent = 'z' + map.getZoom() + ' · ' +
      c.lat.toFixed(4) + ', ' + c.lng.toFixed(4);
  }
  map.on('moveend zoomend', refresh);
  refresh();
})();
</script>
</body>
</html>
Language: the code and this page are in English; the full tutorial and API notes for this example are in Chinese. The demo itself is the authoritative version — it runs exactly as shown.

More Leaflet examples

Leaflet · EXAMPLEBasemap Switch Leaflet · EXAMPLEMinimal Scene Leaflet · EXAMPLECoord Pick