javascript - 如何在 Mapbox GL JS 上的 setHtml 内设置事件?

标签 javascript html mapbox mapbox-gl-js

我在使用以下示例时遇到问题:

mapboxgl.accessToken = 'pk.eyJ1IjoicGFwYWJ1Y2t0IiwiYSI6ImNqa2k3azQ1dzA1Zmgza3B1czIxOGhhaW4ifQ.h5OT3NaQf0vcxx3g1q1cXw';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v9',
    zoom: 5,
    center: [-77.04, 38.907],
});
map.on('load', function() {
        
        map.addLayer({
        "id": "places",
        "type": "symbol",
        "source": {
            "type": "geojson",
            "data": {
                "type": "FeatureCollection",
                "features": [{
                    "type": "Feature",
                    "properties": {
                        "id" : 1,
                        "name" :"My Icon",
                        "icon": "theatre"
                    },
                    "geometry": {
                        "type": "Point",
                        "coordinates": [-77.038659, 38.931567]
                    }
                }]
            }
        },
        "layout": {
            "icon-image": "ferry-15",
            "icon-allow-overlap": true
        }
    });

        map.on('click', 'places', function (e) {
          var coordinates = e.features[0].geometry.coordinates.slice();
          var id = e.features[0].properties.id;
          var name = e.features[0].properties.name;
      
          while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
              coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
          }

          new mapboxgl.Popup()
              .setLngLat(coordinates)
              .setHTML("<table>" +
                    "<tr>" +
                        "<td>ID</td>" +
                        "<td>:</td>" +
                        "<td>"+id+"</td>" +
                    "</tr>" +
                    "<tr>" +
                        "<td>Name</td>" +
                        "<td>:</td>" +
                        "<td>"+name+"</td>" +
                    "</tr>" +
                    "</table>" +
                    "<button type='button' onclick='"+alert("Success")+"'>This Button</button>"

                )
              .addTo(map);
        });

        map.on('mouseenter', 'places', function () {
            map.getCanvas().style.cursor = 'pointer';
        });

        // Change it back to a pointer when it leaves.
        map.on('mouseleave', 'places', function () {
            map.getCanvas().style.cursor = '';
        });


});
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>WEBAPP</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
     <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
</head>
<body>
  <div id='map'></div>
</body>
</html>

我的问题是,我不知道这是错误,或者我写了错误的代码。我期待的结果是,当我单击船舶图标,然后单击名为“此按钮”的按钮时,会显示一条警报。但在这段代码中,当我单击船舶图标时,会显示一条警报,然后弹出。虽然我已经在 setHtml 中设置了 onclick 事件。
我该如何解决 ?谢谢

最佳答案

您连接 HTML 字符串的方式有问题。当您添加 +alert("Success")+"

您实际上是在将警报渲染为 HTML 字符串之前调用该函数

如果你把它替换为

"<button type='button' onclick=alert('Success')>This Button</button>"

您会看到它有效,因为字符串的构造已更正。

我建议您将连接替换为模板文字 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals 干净多了

示例:

.setHTML(`<table> 
                    <tr>
                        <td>ID</td>
                        <td>:</td>
                        <td>${id}</td>
                    </tr>
                    <tr>
                        <td>Name</td>
                        <td>:</td>
                        <td>${name}</td>
                    </tr>
                    </table>
                    <button type="button" onclick="alert('Success on ${name} ${id})">This Button</button>`)

mapboxgl.accessToken = 'pk.eyJ1IjoicGFwYWJ1Y2t0IiwiYSI6ImNqa2k3azQ1dzA1Zmgza3B1czIxOGhhaW4ifQ.h5OT3NaQf0vcxx3g1q1cXw';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v9',
    zoom: 5,
    center: [-77.04, 38.907],
});
map.on('load', function() {
        
        map.addLayer({
        "id": "places",
        "type": "symbol",
        "source": {
            "type": "geojson",
            "data": {
                "type": "FeatureCollection",
                "features": [{
                    "type": "Feature",
                    "properties": {
                        "id" : 1,
                        "name" :"My Icon",
                        "icon": "theatre"
                    },
                    "geometry": {
                        "type": "Point",
                        "coordinates": [-77.038659, 38.931567]
                    }
                }]
            }
        },
        "layout": {
            "icon-image": "ferry-15",
            "icon-allow-overlap": true
        }
    });

        map.on('click', 'places', function (e) {
          var coordinates = e.features[0].geometry.coordinates.slice();
          var id = e.features[0].properties.id;
          var name = e.features[0].properties.name;
      
          while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
              coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
          }

          new mapboxgl.Popup()
              .setLngLat(coordinates)
        .setHTML(`<table> 
                        <tr>
                            <td>ID</td>
                            <td>:</td>
                            <td>${id}</td>
                        </tr>
                        <tr>
                            <td>Name</td>
                            <td>:</td>
                            <td>${name}</td>
                        </tr>
                        </table>
                        <button type="button" onclick="alert('Success on ${name}')">This Button</button>`)
               
              .addTo(map);
        });

        map.on('mouseenter', 'places', function () {
            map.getCanvas().style.cursor = 'pointer';
        });

        // Change it back to a pointer when it leaves.
        map.on('mouseleave', 'places', function () {
            map.getCanvas().style.cursor = '';
        });


});
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>WEBAPP</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
     <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
</head>
<body>
  <div id='map'></div>
</body>
</html>

关于javascript - 如何在 Mapbox GL JS 上的 setHtml 内设置事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53275439/

相关文章:

javascript - 使用 eventRender 在完整日历 api 中附加子元素?

javascript - JS : replace function definition before object instantiation

html - CSS 无法识别来自 div 标记的标识符 (ID)。

javascript - 捕获我的 Canvas 下的内容作为图像的一部分

ios - Mapview委托(delegate)函数在关闭包含mapview的 View Controller 后继续运行

javascript - float 条形图可点击的条显示不正确的信息

javascript - 将 tabindex ="-1"添加到当前菜单项是一个很好的辅助功能实践吗?

html - global wrapper div min-height 100vh 打破固定在移动设备上的 child

Mapbox:在 basemap 上仅显示一个国家?

javascript - 传单 - 如何自动删除以前的标记