如何在mapbox-gl-js中的标记上添加“点击”监听器

问题描述 投票:0回答:6

我使用以下示例在地图上添加了一些标记:

https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/

现在我想在用户单击标记图像时显示弹出窗口,但我找不到优雅的解决方案。有什么帮助吗?

mapbox-gl-js
6个回答
31
投票

我也遇到了同样的问题,但我找到了一种解决方法,而无需创建 html 元素。

我使用了

getElement()
函数,它像 HTML 元素一样返回标记,并在附加单击事件之后。

      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");
        });
      });

18
投票

考虑最近发布的 MapBox-Gl-js。可以直接完成,只需添加带有标记的弹出窗口即可。

// 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);

休息你就可以拥有自己设计的弹出窗口了

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.

供参考https://www.mapbox.com/mapbox-gl-js/example/set-popup/

还有一个更有用的东西,要在标记上附加单击事件,您可以通过在标记元素上附加单击事件侦听器来完成,例如

el.addEventListener('click', () => 
   { 
      alert("Marker Clicked.");
   }
); 

8
投票

以下代码片段来自 Mapbox-gl-js 示例:单击时显示弹出窗口

 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' : '';
});

6
投票

对于初学者来说,在您可能用来向地图添加标记的map.addLayer()函数中,您需要在配置对象中设置 "interactive": true 。

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
                }
            });

之后,您需要在地图上设置一个点击处理程序,并检查该点是否位于您的某个要素(标记)上方。

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]);

      });

    });

您可以在他们的网站查看文档以获取更多信息。如果您有任何问题,请告诉我。


2
投票
<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

这是解决方案。

单独添加点击事件

希望这会有所帮助


0
投票

在 maplibre 上,我可以将 onClick 事件附加到标记,如下所示:

marker.getElement().addEventListener('click', () => console.log('click event'))
© www.soinside.com 2019 - 2024. All rights reserved.