32

How can I temporary disable zoming/draging the Mapview in Leaflet.js Tried so many ways but without any luck. It's important to make it temporary and I also need the option to enable again.

Bernhard
  • 503
  • 2
  • 5
  • 10
  • Any ideas how to do this with CSS? I need to disable dragging on mobile using a media query. I tried setting a transparent layer on top of it but it clicks right through that layer. I even played with pointer-events but no luck. The proper approach is most likely through the use of -webkit-user-drag: none; but I have applied that to every element I can find and still no luck. Thanks. –  Dec 16 '13 at 18:06
  • I answered this question below. – hayatbiralem Jul 06 '18 at 10:20

4 Answers4

58

your going to want to do (assuming your map is call map)

map.dragging.disable();
map.touchZoom.disable();
map.doubleClickZoom.disable();
map.scrollWheelZoom.disable();
map.boxZoom.disable();
map.keyboard.disable();
if (map.tap) map.tap.disable();
document.getElementById('map').style.cursor='default';

turn it on again with

map.dragging.enable();
map.touchZoom.enable();
map.doubleClickZoom.enable();
map.scrollWheelZoom.enable();
map.boxZoom.enable();
map.keyboard.enable();
if (map.tap) map.tap.enable();
document.getElementById('map').style.cursor='grab';
netAction
  • 103
  • 3
Calvin
  • 1,507
  • 13
  • 14
  • 2
    Thank you very much. I was looking so wrong _ thought there must be a single method to do that. – Bernhard Mar 20 '13 at 13:59
  • 1
    This solution has some issues: The mouse cursor is still a hand. Page scrolling with touch gestures is not possible over the map. When the opening of a Popover moves the map it will never pan back. – netAction Mar 16 '15 at 11:35
  • @netAction, Do you have a solution to the touch gesture scrolling issue? – Chris Fremgen Jan 12 '17 at 14:57
  • @ChrisFremgen: map.dragging.disable(); does the trick that the map stops fetching scrolling gestures. – netAction Jan 12 '17 at 15:06
  • Is there a way to only disable zoomIn? – howard.D Mar 22 '17 at 04:09
  • Neither of these answers worked to stop clicks to the map from within the info div. I ended up creating a variable, changing its value on mouseover and mouseout, and checking against this variable in my map.on('click', ...) function before proceeding with the rest of the function. – Malcolm Apr 20 '17 at 17:01
8

If you don't want to disable each handler manually, you can loop over all of them and disable/enable them.

Disable

map._handlers.forEach(function(handler) {
    handler.disable();

});

Enable

map._handlers.forEach(function(handler) {
    handler.enable();

});
ustroetz
  • 7,994
  • 10
  • 72
  • 118
  • Beware that using non public properties (_handlers) may cause error in your code even on leaflet patch version changes as it is not guaranteed to remain unchanged. Feature request should be submitted to leaflet ;) – Luckylooke Sep 22 '17 at 07:35
3

I think, you can wrap your map with a helper container and you can disable it with simple CSS class like is-locked.

Here's what I'm talking about:

.map-container {
  position: relative;
}

.map-container .map {
  position: relative;
  z-index: 1;
}

.map-container.is-locked:after {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  content: "";
  display: block;
}

I hope it helps.

hayatbiralem
  • 131
  • 4
0

I'm using react-leaflet with quite a few custom event handlers added to my leaflet map. I can't just stop propagation on the leaflet domevent because doing so caused issues (esp. with components from other frameworks I'm using such as material-ui).

So in case anybody is in the same boat, here's a solution that's working for me!

import React, { useEffect, useRef } from 'react'
import { DomEvent } from 'leaflet'
import { useLeaflet } from 'react-leaflet'

const PreventLeafletControl = (props) => { const controlRef = useRef() const leaflet = useLeaflet() useEffect(() => { if (controlRef) { const eventsClone = leaflet.map._events const eventsEmpty = Object.keys(eventsClone).reduce((accumulator, key) => accumulator[key] = [] , {}) DomEvent.addListener(controlRef.current, 'mouseover', () => { leaflet.map._events = eventsEmpty leaflet.map._handlers.forEach(handler => handler.disable()) }) DomEvent.addListener(controlRef.current, 'mouseout', () => { leaflet.map._handlers.forEach(handler => handler.enable()) leaflet.map._events = eventsClone }) } })

return <div ref={controlRef}> {props.children} </div> }

export default PreventLeafletControl

Just wrap <PreventLeafletControl> around your custom UI component and you should be good.

wesww
  • 101
  • 1
  • Please avoid duplicate answers: https://gis.stackexchange.com/a/376252/8104. More details here: https://meta.stackexchange.com/q/104227/641151 – Aaron Oct 10 '20 at 02:15