popups for mapbox markers on hover not working

I’m trying to show popups on hover for Mapbox markers.

I have tried following the examples and I got it to work to do what I want showing different marker icons based on a class but it’s the popups that don’t work.

I need to show the popups on the mouse hover of the markers.

I think it has something to do with the data source? Any help would be appreciated. Thanks

My code is as below,

mapboxgl.accessToken = 'example-token-here';
var geojson = {
  'type': 'FeatureCollection',
  'features': [{
      'type': 'Feature',
      'properties': {
        'message': 'Foo',
        'class': 'tree',
        'description': '<strong>Make it Mount Pleasant</strong><p>Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.</p>',
        'iconSize': [60, 60]
      },
      'geometry': {
        'type': 'Point',
        'coordinates': [-66.324462890625, -16.024695711685304]
      }
    },
    {
      'type': 'Feature',
      'properties': {
        'message': 'Bar',
        'description': '<strong>Make it Mount Pleasant</strong><p>Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.</p>',
        'class': 'xmas',
        'iconSize': [50, 50]
      },
      'geometry': {
        'type': 'Point',
        'coordinates': [-61.2158203125, -15.97189158092897]
      }
    },
    {
      'type': 'Feature',
      'properties': {
        'message': 'Baz',
        'description': '<strong>Make it Mount Pleasant</strong><p>Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.</p>',
        'class': 'meadow',
        'iconSize': [40, 40]
      },
      'geometry': {
        'type': 'Point',
        'coordinates': [-63.29223632812499, -18.28151823530889]
      }
    }
  ]
};

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v11',
  center: [-65.017, -16.457],
  zoom: 5
});

// add markers to map
geojson.features.forEach(function(marker) {
  // Get each feature class
  var cls = marker.properties['class'];

  if (cls == 'tree') {
    // create a DOM element for the tree marker

    var el = document.createElement('div');
    el.className = 'marker';
    el.style.backgroundImage =
      'url(https://1mt.brightapps.co/wp-content/uploads/2021/02/tree.png)';
    el.style.width = marker.properties.iconSize[0] + 'px';
    el.style.height = marker.properties.iconSize[1] + 'px';


  }

  if (cls == 'xmas') {
    // create a DOM element for the tree marker

    var el = document.createElement('div');
    el.className = 'marker xmas-marker';
    el.style.backgroundImage =
      'url(https://1mt.brightapps.co/wp-content/uploads/2021/02/xmas.png)';
    el.style.width = marker.properties.iconSize[0] + 'px';
    el.style.height = marker.properties.iconSize[1] + 'px';


  }



  // add marker to map
  new mapboxgl.Marker(el)
    .setLngLat(marker.geometry.coordinates)
    .addTo(map);
});


// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
  closeButton: false,
  closeOnClick: false
});

map.on('mouseenter', geojson, function(e) {
  // Change the cursor style as a UI indicator.
  map.getCanvas().style.cursor = 'pointer';

  var coordinates = e.features[0].geometry.coordinates.slice();
  var description = e.features[0].properties.description;

  // Ensure that if the map is zoomed out such that multiple
  // copies of the feature are visible, the popup appears
  // over the copy being pointed to.
  while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
    coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
  }

  // Populate the popup and set its coordinates
  // based on the feature found.
  popup.setLngLat(coordinates).setHTML(description).addTo(map);
});

map.on('mouseleave', geojson, function() {
  map.getCanvas().style.cursor = '';
  popup.remove();
});
.marker {
  display: block;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
  background-repeat: no-repeat;
  background-size: cover;
}

.mapboxgl-popup {
  max-width: 100px;
}
.as-console-wrapper { max-height: 15% !important; bottom: 0; }
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

<script src='https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.css' rel='stylesheet' />

<div class="container-fluid">
  <div class="row">
    <div class="col-lg-8">
      <div id="map" style="height: 500px;"></div>
    </div>
    <div class="col-lg-4 bg-secondary">
    </div>
  </div>
</div>

15 thoughts on “popups for mapbox markers on hover not working”

  1. There are several concept misunderstandings in your code. You’re creating custom image markers (which are in the end HTML elements) based on a source, but you’re creating the handler at map level over the source, instead attached to the markers. Second, you create one single popup before it’s even instantiated, and then try to position on the event, but also you remove it in the detach event, so even if that would ever run, it’ll run only once.

    If what you want is to show a pop-up on mouseover when the cursor is over one of your trees… I have created [this fiddle for you showing the popup on mouseover][1].
    [![Mousover][2]][2]

    Relevant code is below…

    var geojson = {
        'type': 'FeatureCollection',
        'features': [{
            'type': 'Feature',
            'properties': {
                'message': 'Foo',
                'class': 'tree',
                'description': '<strong>Make it Mount Pleasant</strong><p>Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.</p>',
                'iconSize': [60, 60]
            },
            'geometry': {
                'type': 'Point',
                'coordinates': [-66.324462890625, -16.024695711685304]
            }
        },
        {
            'type': 'Feature',
            'properties': {
                'message': 'Bar',
                'description': '<strong>Make it Mount Pleasant</strong><p>Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.</p>',
                'class': 'xmas',
                'iconSize': [50, 50]
            },
            'geometry': {
                'type': 'Point',
                'coordinates': [-61.2158203125, -15.97189158092897]
            }
        },
        {
            'type': 'Feature',
            'properties': {
                'message': 'Baz',
                'description': '<strong>Make it Mount Pleasant</strong><p>Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.</p>',
                'class': 'meadow',
                'iconSize': [40, 40]
            },
            'geometry': {
                'type': 'Point',
                'coordinates': [-63.29223632812499, -18.28151823530889]
            }
        }
        ]
    };
    
    var map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-65.017, -16.457],
        zoom: 5
    });
    
    // Create a popup, but don't add it to the map yet.
    var popup;
    
    // add markers to map
    geojson.features.forEach(function (marker) {
        // Get each feature class
        var cls = marker.properties['class'];
    
        if (cls == 'tree') {
            // create a DOM element for the tree marker
    
            var el = document.createElement('div');
            el.className = 'marker';
            el.style.backgroundImage =
                'url(https://1mt.brightapps.co/wp-content/uploads/2021/02/tree.png)';
            el.style.width = marker.properties.iconSize[0] + 'px';
            el.style.height = marker.properties.iconSize[1] + 'px';
    
    
        }
    
        if (cls == 'xmas') {
            // create a DOM element for the tree marker
    
            var el = document.createElement('div');
            el.className = 'marker xmas-marker';
            el.style.backgroundImage =
                'url(https://1mt.brightapps.co/wp-content/uploads/2021/02/xmas.png)';
            el.style.width = marker.properties.iconSize[0] + 'px';
            el.style.height = marker.properties.iconSize[1] + 'px';
    
        }
    
        el.addEventListener('mouseover', function () {
            // Change the cursor style as a UI indicator.
            map.getCanvas().style.cursor = 'pointer';
            console.log(marker);
    
            var coordinates = marker.geometry.coordinates.slice();
            var description = marker.properties.description;
    
            // Ensure that if the map is zoomed out such that multiple
            // copies of the feature are visible, the popup appears
            // over the copy being pointed to.
            //while (Math.abs(marker.lngLat.lng - coordinates[0]) > 180) {
            //  coordinates[0] += marker.lngLat.lng > coordinates[0] ? 360 : -360;
            //}
            console.log(coordinates);
            // Populate the popup and set its coordinates
            // based on the feature found.
            popup = new mapboxgl.Popup({
                closeButton: false,
                closeOnClick: false
            }).setLngLat(coordinates).setHTML(description).addTo(map);
        });
    
        el.addEventListener('mouseout', function () {
            map.getCanvas().style.cursor = '';
            popup.remove();
        });
    
    
    
        // add marker to map
        new mapboxgl.Marker(el)
            .setLngLat(marker.geometry.coordinates)
            .addTo(map);
    });
    
    
      [1]: http://which%20are%20in%20the%20end%20HTML%20elements
      [2]: https://i.stack.imgur.com/deiVz.png
      [3]: https://i.stack.imgur.com/arLxc.png
    
    Reply

Leave a Comment