Reputation: 466
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?
Upvotes: 30
Views: 59470
Reputation: 2566
This is a general-purpous MapboxGl code for "click" and "mousemove" events, showing a layer property (you can remove .map and use object itself):
map.on('click', (e) => {
const features = map.queryRenderedFeatures(e.point).map((s)=>s.layer);
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(JSON.stringify(features))
.addTo(map);
});
map.on('mousemove', function (e) {
const features = map.queryRenderedFeatures(e.point);
map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';
});
Upvotes: 0
Reputation: 469
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");
});
});
Upvotes: 35
Reputation: 327
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' : '';
});
Upvotes: 11
Reputation: 3339
on maplibre, I can attach an onClick event to a marker like this:
marker.getElement().addEventListener('click', () => console.log('click event'))
Upvotes: 2
Reputation: 85
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.1/mapbox-gl.css" rel="stylesheet" />
<style>
html, body, #mapContainer {
height: 100%;
margin: 0;
}
/* Change the cursor to a pointer on hover so the user knows it's clickable */
.mapboxgl-marker:hover {
cursor: pointer;
}
/* darken the marker on hover */
.mapboxgl-marker:hover svg > g > g:nth-child(2) {
fill: #7993a5;
}
#info-box {
position: absolute;
z-index: 10;
left: 7px;
font-family: sans-serif;
background: #dedede;
padding: 12px;
border-radius: 8px;
font-size: 2rem;
border: 1px solid #969696;
bottom: 34px;
}
</style>
<div id="mapContainer"></div>
<div id="info-box">Click a City</div>
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.1/mapbox-gl.js'></script>
<script>
mapboxgl.accessToken = 'YOUR MAPBOX TOKEN';
const map = new mapboxgl.Map({
container: 'mapContainer',
style: 'mapbox://styles/mapbox/light-v9',
center: [-100.52, 37.67],
zoom: 3.05,
pitch: 36,
hash: true,
});
// Add zoom and rotation controls to the map.
map.addControl(new mapboxgl.NavigationControl());
// extend mapboxGL Marker so we can pass in an onClick handler
class ClickableMarker extends mapboxgl.Marker {
// new method onClick, sets _handleClick to a function you pass in
onClick(handleClick) {
this._handleClick = handleClick;
return this;
}
// the existing _onMapClick was there to trigger a popup
// but we are hijacking it to run a function we define
_onMapClick(e) {
const targetElement = e.originalEvent.target;
const element = this._element;
if (this._handleClick && (targetElement === element || element.contains((targetElement)))) {
this._handleClick();
}
}
};
const cities = [
{
name: 'New York',
coordinates: [ -73.969145, 40.669116 ],
},
{
name: 'Washington, D.C.',
coordinates: [ -77.047119, 38.856820 ],
},
{
name: 'Chicago',
coordinates: [ -87.662659, 41.865470 ],
},
{
name: 'Seattle',
coordinates: [ -122.266846, 47.591346 ],
},
{
name: 'St. Louis',
coordinates: [ -90.304871, 38.634036 ],
},
{
name: 'Houston',
coordinates: [ -95.377808, 29.754840 ],
},
];
cities.forEach((city) => {
new ClickableMarker()
.setLngLat(city.coordinates)
.onClick(() => { // onClick() is a thing now!
document.getElementById('info-box')
.innerHTML = `You clicked ${city.name}!`;
})
.addTo(map);
});
</script>
https://bl.ocks.org/chriswhong/8977c0d4e869e9eaf06b4e9fda80f3ab
here is the solution for this.
add click event separately
Hope this may help
Upvotes: 2
Reputation: 1110
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.");
}
);
Upvotes: 19
Reputation: 820
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.
Upvotes: 8