Leaflet和Mapbox:通过Javascript添加时按钮不起作用

时间:2016-01-24 20:03:32

标签: javascript leaflet mapbox

任何人都知道为什么单击此按钮时,按钮不会添加或删除地图中的叠加层? Full PLNKR here

HTML

<div id="toggleButtons" style="display: none">
 <button id="add">Add Overlays</button>
 <button id="remove">Remove Overlays</button>
</div>

Javascript

L.Control.GroupedLayers.include({
addOverlays: function () {
    for (var i in this._layers) {
        if (this._layers[i].overlay) {
            if (!this._map.hasLayer(this._layers[i].layer)) {
                this._map.addLayer(this._layers[i].layer);
            }
        }
    }
},
removeOverlays: function () {
    for (var i in this._layers) {
        if (this._layers[i].overlay) {
            if (this._map.hasLayer(this._layers[i].layer)) {
                this._map.removeLayer(this._layers[i].layer);
            }
        }
    }
 }
});

var control = new L.Control.GroupedLayers(ExampleData.Basemaps, {
'Landmarks': {
    'Cities': ExampleData.LayerGroups.cities,
    'Restaurants': ExampleData.LayerGroups.restaurants
},
'Random': {
    'Dogs': ExampleData.LayerGroups.dogs,
    'Cats': ExampleData.LayerGroups.cats
}
}).addTo(map);

L.DomEvent.addListener(L.DomUtil.get('add'), 'click', function () {
control.addOverlays();
});

L.DomEvent.addListener(L.DomUtil.get('remove'), 'click', function () {
control.removeOverlays();
});

然后我添加了mapbox legendControl.addLegend方法(from the mapbox API documentation

map.legendControl.addLegend(document.getElementById('toggleButtons').innerHTML);

虽然按钮显示在地图中,但其点击属性不起作用。有线索吗?谢谢!

2 个答案:

答案 0 :(得分:1)

你没有&#39;添加&#39;使用javascript按钮,您可以复制它们并将副本放入legendControl。带有事件处理程序的实际按钮仍然存在于DOM中但隐藏,因为您已将display: none添加为内联样式。你想要做的是选择按钮并从身体中删除它们:

var buttons = document.getElementById('toggleButtons');
document.body.removeChild(buttons);

然后您可以将它们添加到图例并附加事件处理程序:

var legendControl = L.mapbox.legendControl().addTo(map);

legendControl.addLegend(buttons.innerHTML);

L.DomEvent.addListener(L.DomUtil.get('add'), 'click', function () {
    control.addOverlays();
});

L.DomEvent.addListener(L.DomUtil.get('remove'), 'click', function () {
    control.removeOverlays();
});

关于Plunker的工作示例:http://plnkr.co/edit/7pDkrZbS7Re1YshKZSLs?p=preview

PS。我为什么要滥用mapbox的图例控件类来添加两个按钮,我感到非常困惑。如果您需要自定义控件,您可以使用传单L.Control类创建一个。它使您免于加载您未使用的图例控件类,从而膨胀。

编辑:正如下面的评论中所承诺的那样,将此解决方案推广到您自己的自定义控件中。我将在代码中的所有注释中进行更多解释,但总体思路是采用基本的L.Control接口并向其添加功能和DOM生成:

// Create a new custom control class extended from L.Control
L.Control.Toggle = L.Control.extend({

    // Have some default options, you can also change/set
    // these when intializing the control
    options: {
        position: 'topright',
        addText: 'Add',
        removeText: 'Remove'
    },

    initialize: function (control, options) {
        // Add the options to the instance
        L.setOptions(this, options);
        // Add a reference to the layers in the layer control
        // which is added to the constructor upon intialization
        this._layers = control._layers;
    },

    onAdd: function (map) {
        // Create the container
        var container = L.DomUtil.create('div', 'control-overlaystoggle'),
            // Create add button with classname, append to container
            addButton = L.DomUtil.create('button', 'control-overlaystoggle-add', container),
            // Create remove button with classname, append to container
            removeButton = L.DomUtil.create('button', 'control-overlays-toggleremove', container);

        // Add texts from options to the buttons
        addButton.textContent = this.options.addText;
        removeButton.textContent = this.options.removeText;

        // Listen for click events on button, delegate to methods below
        L.DomEvent.addListener(addButton, 'click', this.addOverlays, this);
        L.DomEvent.addListener(removeButton, 'click', this.removeOverlays, this);

        // Make sure clicks don't bubble up to the map
        L.DomEvent.disableClickPropagation(container);

        // Return the container
        return container;
    },

    // Methods to add/remove extracted from the groupedLayerControl
    addOverlays: function () {
        for (var i in this._layers) {
            if (this._layers[i].overlay) {
                if (!this._map.hasLayer(this._layers[i].layer)) {
                    this._map.addLayer(this._layers[i].layer);
                }
            }
        }
    },

    removeOverlays: function () {
        for (var i in this._layers) {
            if (this._layers[i].overlay) {
                if (this._map.hasLayer(this._layers[i].layer)) {
                    this._map.removeLayer(this._layers[i].layer);
                }
            }
        }
    }

});

现在您可以按如下方式使用新控件:

// Create a new instance of your layer control and add it to the map
var layerControl = new L.Control.GroupedLayers(baselayers, overlays).addTo(map);

// Create a new instance of your toggle control
// set the layercontrol and options as parameters
// and add it to the map
var toggleControl = new L.Control.Toggle(layerControl, {
    position: 'bottomleft',
    addText: 'Add overlays',
    removeText: 'Remove overlays'
}).addTo(map);

我知道,这很快又很脏但是它应该让你对一般的L.Control课可以做些什么有所了解。

以下是关于Plunker的工作示例:http://plnkr.co/edit/7pDkrZbS7Re1YshKZSLs?p=preview

以下是L.Controlhttp://leafletjs.com/reference.html#control

的参考资料

答案 1 :(得分:0)

您需要遵循授权策略..

document.querySelector('body').addEventListener('click',   function(event) {
  if (event.target.id.toLowerCase() === 'add') {
    control.addOverlays();
  }
  if (event.target.id.toLowerCase() === 'remove') {
    control.removeOverlays();
  }
});