最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Leaflet custom control with activeinactive states for performing action - Stack Overflow

programmeradmin1浏览0评论

I am using Leaflet, and I want to have a button labelled "My Control" in the upper-left corner (as shown below) that when I click it, the following happens:

  1. The cursor becomes a crosshair, and the "My Control" button is an "active" state.
  2. I can click once anywhere on the map. When a I click on the map, some action is performed (e.g., printing to the console the lat-lon coordinates of where the user clicked).
  3. After that action is performed, the "My Control" button goes back to an "inactive" state, and the cursor is no longer a crosshair.

How can I implement something like this?

Finally, if the button is in the "active" state, how can I implement it so that clicking the button again makes it go back to the "inactive" state?

var map = L.map('map').setView([48.86, 2.35], 11);

L.Control.MyControl = L.Control.extend({
  onAdd: function(map) {
    var el = L.DomUtil.create('div', 'leaflet-bar my-control');

    el.innerHTML = 'My Control';

    return el;
  },

  onRemove: function(map) {
    // Nothing to do here
  }
});

L.control.myControl = function(opts) {
  return new L.Control.MyControl(opts);
}

L.control.myControl({
  position: 'topleft'
}).addTo(map);

L.tileLayer('https://{s}.tile.openstreetmap/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="">OpenStreetMap</a> contributors'
}).addTo(map);
.my-control {
  background: #fff;
  padding: 5px;
}
<link rel="stylesheet" href="/[email protected]/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="/[email protected]/dist/leaflet-src.js" integrity="sha512-2h9aokfcaYW7k0VPn1JqbQDQCaNQRrZJwetlnQ88yJrtIzGLVW/2StdQKoE+TIVNNTUxf6SVa+2vW2KB2EXnnA==" crossorigin=""></script>

<div id="map" style="height: 200px"></div>

I am using Leaflet, and I want to have a button labelled "My Control" in the upper-left corner (as shown below) that when I click it, the following happens:

  1. The cursor becomes a crosshair, and the "My Control" button is an "active" state.
  2. I can click once anywhere on the map. When a I click on the map, some action is performed (e.g., printing to the console the lat-lon coordinates of where the user clicked).
  3. After that action is performed, the "My Control" button goes back to an "inactive" state, and the cursor is no longer a crosshair.

How can I implement something like this?

Finally, if the button is in the "active" state, how can I implement it so that clicking the button again makes it go back to the "inactive" state?

var map = L.map('map').setView([48.86, 2.35], 11);

L.Control.MyControl = L.Control.extend({
  onAdd: function(map) {
    var el = L.DomUtil.create('div', 'leaflet-bar my-control');

    el.innerHTML = 'My Control';

    return el;
  },

  onRemove: function(map) {
    // Nothing to do here
  }
});

L.control.myControl = function(opts) {
  return new L.Control.MyControl(opts);
}

L.control.myControl({
  position: 'topleft'
}).addTo(map);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
.my-control {
  background: #fff;
  padding: 5px;
}
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js" integrity="sha512-2h9aokfcaYW7k0VPn1JqbQDQCaNQRrZJwetlnQ88yJrtIzGLVW/2StdQKoE+TIVNNTUxf6SVa+2vW2KB2EXnnA==" crossorigin=""></script>

<div id="map" style="height: 200px"></div>

Share Improve this question edited yesterday Software Dev asked yesterday Software DevSoftware Dev 1,1023 gold badges14 silver badges34 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Something like this could be done :

var mapDiv = map.getContainer();

L.Control.MyControl = L.Control.extend({
      onAdd: function(map) {
        // Made it into a button
        var el = L.DomUtil.create('button');
        el.id = "my-control";
        el.innerHTML = 'My Control';

        // On click, toggle a specific class for CSS styling
        el.addEventListener("click", function(e) {
          // This prevents activating the map click event when clicking on the control
          L.DomEvent.stopPropagation(e);

          // Chose better class names or use data attributes
          e.target.classList.toggle("active");
          mapDiv.classList.toggle("crosshair-cursor")
        })

        // The map event (logging coordinates)
        // Only when button is active (this is why a data attribute might be better)
        L.DomEvent.on(map, "click", function(e) {
          if (!el.classList.contains("active")) {
            return;
          }
          console.log(e.latlng);
        })

        return el;
      },

CSS :

.my-control {
  background: #fff;
  padding: 5px;
}

#my-control {
  cursor: pointer;
  z-index: 100;
}

#my-control.active {
  background-color: gold;
}

#map.crosshair-cursor {
   cursor: crosshair;
}

This is very basic but does what you wanted and can be customized.

发布评论

评论列表(0)

  1. 暂无评论