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.
single HTML file · CDN dependencies onlyinterface may contain Chinese labels
Source
<!--
示例:缩放滑块
要点: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.