Adding popups on hovering to custom markers using Mapbox gl js
Asked Answered
C

3

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?

Chemiluminescence answered 18/1, 2019 at 13:3 Comment(0)
B
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/

Blip answered 18/1, 2019 at 18:11 Comment(3)
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: jsfiddle.net/anton9ov/0ewy48uLChemiluminescence
I edited my answer to include the issue of preventing clicks :)Blip
Been looking all over the web. Mans your solution is the simplest and best.Demaggio
P
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>
Pinetum answered 28/11, 2019 at 13:37 Comment(0)
S
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())
Salpingitis answered 14/11, 2022 at 14:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.