Fügen Sie einen Ereignis-Listener zu einem Marker in der Broschüre hinzu


10

Ich benutze Leaflet, um eine Karte zu rendern. Ich habe eine Karte mit Markierungen erstellt und weiß nicht, wie ich den Ereignis-Listener 'onClick' für jede Markierung implementieren soll.

Mein Code

var stops = JSON.parse(json);
var map = new L.Map('map', {
  zoom: 12,
  minZoom: 12,
  center: L.latLng(41.11714, 16.87187)
});
map.addLayer(L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
  attribution: 'Map data',
  maxZoom: 18,
  id: 'mapbox.streets',
  accessToken: '-----'
}));
var markersLayer = new L.LayerGroup();
map.addLayer(markersLayer);


//populate map from stops
for (var i in stops) {
  L.marker(L.latLng(stops[i].Position.Lat, stops[i].Position.Lon), {
    title: stops[i].Description
  }).addTo(markersLayer).bindPopup("<b>" + stops[i].Description + "</b>").openPopup();
}

Beispiel

map.on('click', function(e) {
    alert(e.latlng);
});

Die Broschüre behandelt Ereignis-Listener als Referenz. Wenn Sie also einen Listener hinzufügen und dann entfernen möchten, definieren Sie ihn als Funktion:

function onClick(e) { ... }

map.on('click', onClick);
map.off('click', onClick);

Siehe @ TimoSperisens Antwort auf diese Frage und die Geige, die er gepostet hat. Es funktioniert für mich
Mawg sagt, Monica

Antworten:


14

Willkommen bei GIS Stack Exchange!

Es sollte keine besonderen Schwierigkeiten geben, einen Rückruf an das Klickereignis der Markierung (en) anzuhängen. Sie würden einfach so verwenden, myMarker.on('click', callback)wie Sie es mit der Karte getan haben. Sie müssten dies auch für jeden Marker tun, an den Sie einen Rückruf anhängen möchten.

Eine andere Möglichkeit wäre, alle Ihre Markierungen in eine hinzufügen Feature Reihe (zB einfach Ihre instanziiert markersLayermit L.featureGroup()statt L.layerGroup()), so dass Sie den Rückruf anhängen kann direkt an die Gruppe. Es werden die Klickereignisse von einzelnen Markierungen empfangen, und Sie können mit auf die einzelne angeklickte Funktion zugreifen event.layer.

var markersLayer = L.featureGroup().addTo(map);

// populate map from stops…

markersLayer.on("click", function (event) {
    var clickedMarker = event.layer;
    // do some stuff…
});

Demo: http://jsfiddle.net/ve2huzxw/74/

Ähnliche Fragen, die von jemand anderem im Leaflet-Forum gestellt wurden: https://groups.google.com/forum/#!topic/leaflet-js/RDTCHuLvMdw


Durch einfaches Hinzufügen erhalten event.layer.propertiesSie Zugriff auf das Array aller Eigenschaften (Metadaten) Ihrer Marker gemäß dem GeoJSON-Format. So können Sie event.layer.properties.description = stops[i].Descriptionzum Beispiel zuweisen .
Nikhil VJ

4

Ändern Sie Ihre Kartenpopulationsschleife, um Ihrem Marker Eigenschaften zuzuweisen.

//populate map from stops
for (var i in stops) {
  var oneMarker = L.marker(L.latLng(stops[i].Position.Lat, stops[i].Position.Lon), {
    title: stops[i].Description
  }).bindPopup("<b>" + stops[i].Description + "</b>").openPopup();

  oneMarker.properies.name = stops[i].Name;
  oneMarker.properies.description = stops[i].Description;
  oneMarker.properies.othervars = stops[i].othervars;
  oneMarker.addTo(markersLayer);
}

Um später im onclick-Ereignis auf diese Eigenschaften (so genannte Feature-Eigenschaften) zuzugreifen,

markersLayer.on("click", markerOnClick);

function markerOnClick(e) {
  var attributes = e.layer.properties;
  console.log(attributes.name, attributes.desctiption, attributes.othervars);
  // do some stuff…
}

Der properties.varAnsatz hat den zusätzlichen Vorteil, dass Ihr Marker im Standard-GeoJson-Format vorliegt. Macht es kompatibel, wenn Sie beispielsweise die Daten als Shapefile exportieren, Markierungen aus Shapefile importieren usw. müssen.


1
Ich versuche, Ihren Vorschlag in mein eigenes Setup aufzunehmen. Wenn ich jedoch eine einfache oneMarker.properties hinzufüge, wird die Fehlermeldung "oneMarker.properties ist undefiniert" angezeigt. Ich übersehen etwas Offensichtliches? btw Aspekte anbelangt: Sie falsch geschrieben properies ........ Eigenschaften in Ihrem Beispiel - Code
alex

1
Ah, ich glaube, ich habe eine Lösung gefunden: Ich musste oneMarker.properties = {} hinzufügen. Übrigens: Ist es richtig, var oneMarker zu verwenden, oder sollte dies ein dynamischer Name sein?
Alex

@alex gut über die Eigenschaften Hack zu wissen. Ja, es ist in Ordnung zu verwenden var oneMarker- es ist ein lokaler Bereich innerhalb der for-Schleife, und die Zeile layer.addTo () fügt den Wert hinzu. (wie: a=3; array1.push[a];wird 3dem Array einen Mehrwert hinzufügen , kein Verweis auf sich aselbst.)
Nikhil VJ

0

Eine ziemlich einfache und einfache Möglichkeit, ein Array anklickbarer Markierungen in einem Faltblattkartenobjekt zu erstellen, besteht darin, die Klassenliste der erstellten Markierung zu bearbeiten, indem jeder Markierung ein benutzerdefinierter inkrementierter Klassenname hinzugefügt wird. Dann ist es einfach, einen Listener zu erstellen und zu wissen, auf welchen Marker geklickt wurde. Durch Überspringen des aktiven oder nicht aktiven Ereignisses verfügt jedes über ein abrufbares Klickereignis mit einer zuverlässigen ID.

  // creates markers, each with a leaflet supplied class
  if (length === 1) {
    for (i = 0; i < parks.length; ++i) {
      if (parks[i].parksNumber !== parks.parksNumber)
        L.marker([parks[i].latitude, parks[i].longitude], {
          icon: parks[i].iconMarker
        }).addTo(mymap);
    }
  }

  // select all of the leaflet supplied class
  let markers = document.querySelectorAll(".leaflet-marker-icon");

  // loop through those elements and first assign the indexed custom class
  for (i = 0; i < markers.length; ++i) {
    markers[i].classList.add("marker_" + parks[i].parksNumber);

    // then add a click listener to each one
    markers[i].addEventListener("click", e => {

      // pull the class list
      let id = String(e.target.classList);

      // pull your unique ID from the list, be careful cause this list could 
      // change orientation,  if so loop through and find it
      let parksNumber = id.split(" ");
      parksNumber = parksNumber[parksNumber.length - 1].replace("marker_", "");

      // you have your unique identifier to then do what you want with
      search_Number_input.value = parksNumber;
      HandleSearch();
    });
  }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.