18
votes

I added few markers on the map using folowing this example:

https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/

Now I want to show popup when user clicks on marker image, but i can not find elegant solution. Any help?

4

4 Answers

18
votes

I also had the same problem but I found a workaround without having to create an html element.

I Used getElement() function that return Marker like a HTML Element and after i attach the click event.

      this.service.getAllData().forEach(e => {
        // create MapBox Marker
        const marker = new mapboxgl.Marker().setLngLat([e.lon, e.lat]).addTo(this.map);
        // use GetElement to get HTML Element from marker and add event
        marker.getElement().addEventListener('click', () => {
          alert("Clicked");
        });
      });
13
votes

Considering the recent release of MapBox-Gl-js. It can be directly done, just by adding the popup with the marker.

// create a simple popup.
var popup = new mapboxgl.Popup({offset: 25})
    .setText('Construction on the Washington Monument began in 1848.');

// create DOM element for the marker
var el = document.createElement('div');
el.innerHTML = "Marker1";
el.id = 'marker';

// create the marker
new mapboxgl.Marker(el, {offset:[-25, -25]})
    .setLngLat(monument)
    .setPopup(popup) // sets a popup on this marker
    .addTo(map);

Rest you can have your own designed pop-up

var html = '<div class="marker-popup">I am a custom pop-up</div>';

var customPopUp = new mapboxgl.Popup(
    {
       anchor: 'bottom',   // To show popup on top
       offset: { 'bottom': [0, -10] },  // To prevent popup from over shadowing the marker.
       closeOnClick: false   // To prevent close on mapClick.
    }
).setHTML(html); // You can set any valid HTML.

For reference https://www.mapbox.com/mapbox-gl-js/example/set-popup/

One more useful stuff, To attach an on click event on marker, you can do it by attaching click event listener on the marker element like

el.addEventListener('click', () => 
   { 
      alert("Marker Clicked.");
   }
); 
6
votes

For starters, in the map.addLayer() function you probably used to add the markers to the map, you need to set "interactive": true in the configuration object.

map.addLayer({
                "id": "YOUR LAYER ID",
                "interactive": true,
                "type": "symbol",
                "source": "YOUR LAYER SOURCE",
                "layout": {
                  "icon-image": "YOUR LAYER ICON IMAGE",
                  "text-font": "Open Sans Semibold, Arial Unicode MS Bold",
                  "text-offset": [0, 0.6],
                  "text-anchor": "top"
                },
                "paint": {
                  "text-size": 12,
                  "icon-size": 1,
                  "icon-opacity": 0
                }
            });

After that, you need to set a click handler on your map along with a check to see if the point is over one of your features (markers).

map.on('click', function(e) {

    console.log(e);

      map.featuresAt(e.point, {radius: 100, layer: 'YOUR MARKER LAYER ID'}, function(err, features) {
            console.log(features[0]);

      });

    });

You can check the docs at their website for more information. Let me know if you have any problems.

3
votes

The below snippet is from Mapbox-gl-js example: Display a popup on click

 map.on('click', function (e) {
    var features = map.queryRenderedFeatures(e.point, { layers: ['places'] });

    if (!features.length) {
        return;
    }

    var feature = features[0];
    //Use Feature and put your code
    // Populate the popup and set its coordinates
    // based on the feature found.
    var popup = new mapboxgl.Popup()
        .setLngLat(feature.geometry.coordinates)
        .setHTML(feature.properties.description)
        .addTo(map);
});

   // Use the same approach as above to indicate that the symbols are clickable
   // by changing the cursor style to 'pointer'.

map.on('mousemove', function (e) {
    var features = map.queryRenderedFeatures(e.point, { layers: ['places'] });
    map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';
});