Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop Interactions (Click, Drag) from propagating on Control (leaflet)

I have a map with a custom control that changes when I click on a popup.

The map looks like this: Map with control

My Problem is that I can move the map even when my mouse pointer is inside the control. The same happens for a Slider that is not shown in the image.

The code for my control looks as follwing:

var info = L.control({position: "topleft"});

info.onAdd = function (map) {
    // create a div with a class "info"
    this._div = L.DomUtil.create('div', 'info');
    this.update();
    return this._div;
};

The update() function is later added to the info via info.update = ....

My specific question is: How can I stop the events like "click", drag etc. from registering with the underlying map?

I have tried several things, mostly L.DomEvent.disableClickPropagation(info) and L.DomEvent.stopPropagation(e) in several places. I also wanted do change the info.on("click", ...) method, but it seems that controls have no .on(), which I found confusing as well.

I have tried to find an answer via google and SO. Having tried several approaches while none of them working, paired with my confusion about the general workings (there seems to be no easy + bulletproof method) lead me to post my own question.

In general, as I seem confused on it, I would like to know:

  1. How do events work with leaflet? (Why do ALL seem to go to map?)
  2. How do I access elements? (In above case, would it be .disableClickPropagation(info); or var div = L.DomUtil.get(info); div.disable... or var div = L.DomUtil.get("info"); div.disable...

I do have an minimal example at http://jsfiddle.net/s8q35xhu/2/ which shows how the info box is set up and where you can see the problem.

I do hope we find a solution for this and can bring clarity to leaflet event propagation. I would be happy if it eventually worked.

Btw, this is my first question on SO. I would be happy on feedback about the style of the post too :)

like image 344
Kai Hatje Avatar asked Jun 04 '16 09:06

Kai Hatje


1 Answers

Not sure if that causes your problems, but for me it helps to first create an info control and then instantiate it:

var InfoControl = L.Control.extend({
    options: {
        position: "topleft"
    },
    onAdd: function(map) {
        this._div = L.DomUtil.create('div', 'info');
        L.DomEvent.disableClickPropagation(this._div);
        this.update();
        return this._div;
    },
    update: function(d) {
        this._div.innerHTML = '<h4>Job Infos</h4> Click on a popup';
    }
});

var info = new InfoControl().addTo(map);

Note the L.DomEvent.disableClickPropagation(this._div); I added, which succesfully prevents the map from being dragged through the info control. (demo)

Events in Leaflet.

Events go to the map, because Leaflet is a mapping library, and it's about the map. Controls have no .on() method because they do not emit events, the DOM elements contained in the control might, that's why you need to do disableClickPropagation() on the actual DOM element of the control.

like image 172
Jieter Avatar answered Oct 01 '22 07:10

Jieter