能否向leaflet图层组和图层控件添加自定义HTML?

5
有没有一种方法可以将自定义 HTML 注入到图层组和图层控制中?
在我们的应用程序中,我们已经实现了滑块(input:range)来调整不透明度设置,很明显,在其控制容器内为基础图层创建一个专用滑块是有意义的。没有选项或参数可以修改此控件: existing layer group control 理想情况下,我们想在这个组和图层控制中创建一个自定义滑块(显然,我们的“基础图层”控件组仅限于单组图层选项): example of what we'd like to achieve 感谢任何帮助!
3个回答

4

默认代码无法实现此功能。

但是,您可以扩展图层控件并创建一个子类,增加一些额外的功能,例如:

L.Control.Layers.WithSomethingExtra = L.Control.Layers.extend({
  _initLayout: function() {
    L.Control.Layers.prototype._initLayout.call(this);
    L.DomUtil.create('div', 'leaflet-control-layers-separator', this._form);
    var myThing = L.DomUtil.create('div', 'some-extra-thing', this._form);
    myThing.innerHTML = 'My custom thing inside the layers control!!';
  }
});

这里可以看到一个可工作的演示。

如果您感到困惑,请阅读src/control/Control.Layers.js的源代码,以及有关创建插件的Leaflet教程


谢谢Ivan。不幸的是,它似乎只适用于innerHTML中的基本文本;切换到<input/>控件会导致错误:无法读取未定义的“layer”属性。有任何想法吗? - Greg Rowles
我在这里实现了一个自定义hack:https://playground-leaflet.rhcloud.com/xunu/1/edit?html,output 我认为现在这个应该可以工作了。 - Greg Rowles

0

0

如果您不想破坏扩展leaflet类(我尝试了IvanSanches的建议,但对我没有用),还有另一种可能的解决方案,虽然我不知道它是否正是您所希望的,但当我想要为leaflet图层创建“自定义容器”时,它对我很有效。这将需要少量CSS来删除/替换图层控件的leaflet样式

  1. 按照您已经拥有的方式创建L.Control.Layers
  2. 创建一个基本的L.Control图层“父级”,作为您的滑块和图层控件的容器
  3. 将您的滑块(和任何其他自定义元素)作为父容器中的子元素添加
  4. 将您的图层控件作为此容器中的另一个子元素添加
  5. 禁用父图层上的点击传播(否则,当您单击滑块时,它将穿过下面的地图)
  6. 使用CSS从图层控件中删除leaflet样式
// FIRST DEFINE YOUR "layerControl" AND ADD IT TO THE MAP
// of course this assumes you already created the "baseMaps" object
// and in your case are not adding overlayLayers to this control
// so you can set that argument to "undefined"
let layerControl = L.control.layers(baseMaps, undefined, {
  collapsed: false // you won't want this layer to be collapsed
}).addTo(map);

// ******** !! MOST IMPORTANT PART 1.1 !! ********
// GRAB A REFERENCE TO THE DIV THAT CONTAINS THE "layerControl"
let layerControlDiv = layerControl.getContainer();

// you can set an id for it if you want to use it to override the CSS later
layerControlDiv.setAttribute("id", "layer-control-id");

// CREATE A BASIC CONTROL LAYER THAT YOU WILL USE AS A PARENT/CONTAINER FOR THE "layerControl"
// Set its position to where you want it to appear on the map
let layerControlParentLayer = L.control({
  position: "topright"
});

// DEFINE THE PARENT LAYER'S ".onAdd" FUNCTION AND APPEND THE "layerControl" SOMEWHERE WITHIN IT
// This is where the magic happens. Provides similar functionality to IvanSanches's solution
layerControlParentLayer.onAdd = function(map){
  // Create the main div that will hold all your elements
  let parentDiv = L.DomUtil.create("div");
  // let parentDiv = L.DomUtil.create("div", "layer-control-parent-class"); //use this create method if you want to give it a class

  // you can set an id for it if you want to use it for CSS
  parentDiv.setAttribute("id", "layer-control-parent-id");

  // TEMPORARILY: set the background color to be white so the boundaries of the parentDiv are visible
  // you'll actually want to style the whole thing in your CSS code and remove this line
  parentDiv.setAttribute("style", "background-color: white;");
  
  // create another div to hold your slider and append it to your parentDiv
  let sliderDiv = L.DomUtil.create('div', 'slider-div-class', parentDiv);

  // set the innerHTML to be the HTML for your slider
  sliderDiv.innerHTML = '<input type="range" min="0" max="100" value="0" id="slider-id" class="slider-class" >';

  // OPTIONAL: create a separator if you want and append it to the your parentDiv
  L.DomUtil.create('div', 'leaflet-control-layers-separator', parentDiv);
  
  // ******** !! MOST IMPORTANT PART 1.2 !! ********
  // now you can append the overlayControlDiv that holds your overlay layer controls
  parentDiv.appendChild(layerControlDiv);

  // ...
  // add more stuff after the layerControlDiv if you want
  // ...

  // ******** !! MOST IMPORTANT PART 2 !! ********
  // we don't want clicks on this layer/div to propagate to the layers below,
  // otherwise our custom slider will be hard to interact with
  L.DomEvent.disableClickPropagation(parentDiv);

  // return the parentDiv to be used as the div for your layerControlParent Layer
  return parentDiv;
};

// add the Layer to the map
layerControlParentLayer.addTo(map);

需要在 CSS 中进行调整才能使其看起来正确。 当然,这看起来会相当奇怪,因为 "layerControl" 有自己的样式,这些样式是从 leaflet 的 css 中设置的。您需要微调自己 CSS 中的样式以解决这个问题。 主要只需删除 leaflet 容器样式即可。
#layer-control-id{
  margin: 0px;
  padding: 0px;
  border: 0px;
  background: none;
  box-shadow: none;
}

希望这对您有所帮助并解决了您的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接