Adicionar um ouvinte de evento em um Marcador no Leaflet


10

Estou usando o Leaflet para renderizar um mapa. Criei um mapa com marcadores e não sei como implementar o Event Listener 'onClick' em cada Marcador.

Meu código

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();
}

Exemplo

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

O folheto trata dos ouvintes de eventos por referência; portanto, se você deseja adicionar um ouvinte e removê-lo, defina-o como uma função:

function onClick(e) { ... }

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

Ver resposta da @ TimoSperisen a esta pergunta e violino que ele postou Ele funciona para mim
MAWG diz Reintegrar Monica

Respostas:


14

Bem-vindo ao GIS Stack Exchange!

Não deve haver dificuldade especial em anexar um retorno de chamada ao evento de clique do (s) marcador (s). Você simplesmente usaria myMarker.on('click', callback)como no mapa. Você também teria que fazer isso para cada marcador ao qual deseja anexar um retorno de chamada.

Outra possibilidade seria adicionar todos os seus marcadores a um grupo de recursos (por exemplo, instancie seu markersLayercom em L.featureGroup()vez de L.layerGroup()), para que você possa anexar o retorno de chamada diretamente a esse grupo. Ele receberá os eventos de clique de marcadores individuais e você pode acessar o recurso clicado individual usando event.layer.

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

// populate map from stops…

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

Demonstração: http://jsfiddle.net/ve2huzxw/74/

Pergunta semelhante feita por outra pessoa no fórum do Leaflet: https://groups.google.com/forum/#!topic/leaflet-js/RDTCHuLvMdw


Apenas para adicionar, event.layer.propertiesvocê terá acesso à matriz de todas as propriedades (metadados) de seus marcadores, conforme o formato GeoJSON. Então você pode atribuir, event.layer.properties.description = stops[i].Descriptionpor exemplo.
Nikhil VJ

4

Modifique o loop de preenchimento do mapa para atribuir propriedades ao seu marcador.

//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);
}

Mais tarde, para acessar essas propriedades (propriedades do recurso como são chamadas) no evento onclick,

markersLayer.on("click", markerOnClick);

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

A properties.varabordagem tem o benefício adicional de fazer com que seu marcador esteja no formato padrão GeoJson. Torna-o compatível se, por exemplo, você precisar exportar os dados como shapefile, importar marcadores do shapefile, etc.


1
Estou tentando incorporar sua sugestão em minha própria instalação. Mas adicionar um oneMarker.properties simples me dá uma mensagem de erro "oneMarker.properties está indefinido". Estou com vista para algo óbvio? relação BTW: você grafada properies ........ propriedades em seu código exemplo
alex

1
ah acho que encontrei uma solução: tive que adicionar oneMarker.properties = {}; btw: é correto usar var oneMarker ou esse deve ser um nome dinâmico?
1728 alex

@alex bom saber sobre as propriedades hackear. Sim, é bom usar var oneMarker- é o escopo local dentro do loop for e a linha layer.addTo () adiciona valor. (como: a=3; array1.push[a];irá agregar valor 3para a matriz, não uma referência a asi mesmo.)
Nikhil VJ

0

Uma maneira bastante direta e fácil de conseguir criar uma matriz de marcadores clicáveis ​​em um objeto de mapa de folheto é manipular a lista de classes do marcador criado adicionando um nome de classe incrementado personalizado a cada marcador. Então é fácil criar um ouvinte e saber em qual marcador foi clicado. Ignorando o ativo ou não, cada um tem um evento de clique recuperável com um ID confiável.

  // 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();
    });
  }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.