7

I'm adopting this example but I need popups to appear on hover not on click. Here is how popups are added now:

new mapboxgl.Marker(el, {
  offset: [0, -25]
})
.setLngLat(marker.geometry.coordinates)
.setPopup(new mapboxgl.Popup()//add popups
    .setHTML('<h3>' + marker.properties.title + '</h3><p><a href="' + marker.properties.link + '" target="_blank">' + marker.properties.description + '</a></p><p><a href="' + marker.properties.link + '" target="_blank"><img src="' + marker.properties.picture + '" title="" /></a></p>'))
.addTo(map);

It is my jsFiddle, could anyone help me to fix that problem?

Anton
  • 453
  • 1
  • 9
  • 20

3 Answers3

19

mapboxgl.Marker are implemented as simple HTML <div> elements. You can attach standard event listener to them and toggle the popup manually:

const marker = new mapboxgl.Marker({/* options */});
const markerDiv = marker.getElement();

markerDiv.addEventListener('mouseenter', () => marker.togglePopup());
markerDiv.addEventListener('mouseleave', () => marker.togglePopup());

See docs: https://docs.mapbox.com/mapbox-gl-js/api/#marker#getelement

EDIT: Preventing the popup from opening on click

I did some testing, and the only thing reliably working is to call marker.togglePopup() in your own click handler

map.on('click', event => {
  const target = event.originalEvent.target;
  const markerWasClicked = markerDiv.contains(target);

  marker.togglePopup();
});

Full example: https://jsfiddle.net/am2jwtzg/

bbrame
  • 18,031
  • 10
  • 35
  • 52
Scarysize
  • 4,131
  • 25
  • 37
  • That works, thanks. Popups appear on hover now, but they still appear on click as well. Could you tell me how to leave them only on hover? That's jsfiddle with additions: https://jsfiddle.net/anton9ov/0ewy48uL/ – Anton Jan 21 '19 at 13:48
  • 1
    I edited my answer to include the issue of preventing clicks :) – Scarysize Jan 21 '19 at 17:12
  • 1
    Been looking all over the web. Mans your solution is the simplest and best. – mrKindo Jul 24 '20 at 19:26
6

Scarysize answer is working. However, if you click on the marker while you hover over it, the pop-up will be closed and on leaving the marker the pop-up will open again.

To prevent this behaviour you should use the methods marker.addTo(map) and marker.remove() These methods are used internally by the marker.togglePopup() function: Marker source

togglePopup() {
    var popup = this._popup;

    if (!popup) return;
    else if (popup.isOpen()) popup.remove();
    else popup.addTo(this._map);
}

working example below

mapboxgl.accessToken = 'pk.eyJ1IjoibW9ycGhvY29kZSIsImEiOiJVMnRPS0drIn0.QrB-bpBR5Tgnxa6nc9TqmQ';

var monument = [-77.0353, 38.8895];
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v9',
    center: monument,
    zoom: 15
});

// create the popup
var popup = new mapboxgl.Popup(
 {offset:[28, 0]}
).setText(
 'Construction on the Washington Monument began in 1848.'
);
// create the marker
let marker = new mapboxgl.Marker().setLngLat(monument);

// get the marker element
const element = marker.getElement();
element.id = 'marker'
// hover event listener
element.addEventListener('mouseenter', () => popup.addTo(map));
element.addEventListener('mouseleave', () => popup.remove());

// add popup to marker
marker.setPopup(popup);
// add marker to map
marker.addTo(map);
#map { position:absolute; top:0; bottom:0; width:100%; }
#marker {
    background-image: url('https://www.mapbox.com/mapbox-gl-js/assets/washington-monument.jpg');
    background-size: cover;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    cursor: pointer;
}

.mapboxgl-popup {
    max-width: 200px;
}
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.28.0/mapbox-gl.css" rel="stylesheet"/>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.28.0/mapbox-gl.js"></script>
<div id="map"></div>
Visores
  • 4,008
  • 4
  • 18
  • 29
0

in my case this worked

const marker = new mapboxgl.Marker()
        .setLngLat(coords)
        .addTo(this.map)        
    const popup = new mapboxgl.Popup().setHTML('Popup text')
    const markerDiv = marker.getElement()
    markerDiv.addEventListener('mouseenter', () => {
        marker.setPopup(popup)
        marker.togglePopup()
    })
    markerDiv.addEventListener('mouseleave', () => marker.togglePopup())
c.m.
  • 320
  • 2
  • 9