简体   繁体   中英

Set view and trigger click on marker from external HTML in mapbox

I have some external HTML (that is generated from GeoJSON) that has a list of markers that on the map. An example of an item is:

<ul id="marker-list">
    <li data-lat="53.3895673" data-lng="-1.4725166">Marker 1</li>
</ul>

Then I have the following jQuery that listens for a click event on one of the items and should then focus on those coordinates and trigger the click event on the marker (to open its popup).

$(document).on('click', '#marker-list li', function(e){
    e.preventDefault();
    var latlngPoint = new L.latLng($(this).attr('data-lat'), $(this).attr('data-lng'));
    map.setView(latlngPoint, 18);
    map.fireEvent('click', {
        latlng: latlngPoint,
        layerPoint: map.latLngToLayerPoint(latlngPoint),
        containerPoint: map.latLngToContainerPoint(latlngPoint)
    });
});

The setView works fine but the popup isn't being opened...

Adding:

map.on('click', function(e){
   console.log(e);
});

Reveals that the click event is being fired, but it doesn't cause the popup to open... How can I get the popup to open? Is there a way to target the marker instead?

Okay so I solved this by targeting the marker directly using an ID!

First I added an ID to the geoJSON data like so:

"properties": {
  "id": "marker-1",
  "marker-color": "#00ff00",
  "marker-size": "large",
  "marker-symbol": 1
}

Then added the id to the marker list so it became:

<ul id="marker-list">
    <li data-id="marker-1" data-lat="53.3895673" data-lng="-1.4725166">Marker 1</li>
</ul>

For those that want to know how to do this:

var myLayer = L.mapbox.featureLayer().loadURL('/geojson.json').on('ready', run).addTo(map);

function run()
{
    map.fitBounds(myLayer.getBounds(), {padding: [40,40]});

    $('#marker-list').html('');
    var markerList = document.getElementById('marker-list');

    myLayer.eachLayer(function(layer) {

        var html = '\
        <li data-id="' + layer.toGeoJSON().properties.id + '" data-lat="' + layer.toGeoJSON().geometry.coordinates[1] + '" data-lng="' + layer.toGeoJSON().geometry.coordinates[0] + '">\
        </li>';
        $('#marker-list').append(html);

        layer._icon.id = layer.toGeoJSON().properties.id;

    });

}

Then changed my event listener to:

$(document).on('click', '#marker-list a', function(e){
    e.preventDefault();
    var latlngPoint = new L.latLng($(this).attr('data-lat'), $(this).attr('data-lng'));
    map.setView(latlngPoint, 18);
    $('#' + $(this).attr('data-id')).trigger('click');
});

And that works perfectly! Actually there is a slight bug whereby panning manually causes the trigger events to no longer work but if you click the map then it fixes it again (until you pan again)... Not sure why this is happening though :/


Okay I have a fix for the issue above. Basically add the markers to a global array during the eachLayer loop. eg globalMarkers.push(layer);

And also append the loop index to the marker list so you have something like:

<li data-index="2">Marker 2</li>

Then you can literally just use that index to call the popup for that marker like this:

globalMarkers[$(this).attr('data-index')].openPopup();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM