You're right: Mapbox GL JS doesn't store references to markers. However, you can store your own references to the markers in an array at the time that you generate them.
In this example below, I am looping over a set of GeoJSON point features and creating a custom HTML marker for each:
let markersArray = [];
geojson.features.forEach(feature => {
// create a HTML element for each feature
let el = document.createElement("div");
el.className = "marker";
el.innerHTML = `
<img src="custom-marker.png" height="20px" width="20px" />
<span class="marker-label">${feature.properties.name}</span>
`;
// make a marker for each feature and add to the map
let marker = new mapboxgl.Marker({
element: el,
anchor: "top"
})
.setLngLat(feature.geometry.coordinates)
.addTo(map);
// add to my own array in an object with a custom 'id' string from my geojson
markersArray.push({
id: feature.properties.id,
marker
});
});
This id string can be whatever you want. You can even store other parameters if you want to be able to query other things, like latitude/longitude:
markersArray.push({
id: feature.properties.id,
coordinates: feature.geometry.coordinates,
marker
});
Then, if I want to access the marker's instance members (like setDraggable), I can use Array.find() to return the first instance that matches my search parameters in markersArray:
let someIdQuery = "some-id";
let queriedMarkerObj = markersArray.find(
marker => marker.id === someIdQuery
);
queriedMarkerObj.marker.setDraggable(true);
(Note that Array.find() just returns the first instance in the array that matches your condition. Use something like Array.filter() if you want to be able to query for more than one marker.)