如何为 Leaflet.js 标记保存 class 属性

how to keep class attribute stored for Leaflet.js markers

所以我有一组标记,每个标记都存储在不同的图层中...可以说:

let earth= {
    layer:{
        ...
        Markers:{...}
    }
}
let mars= {
    layer:{
        ...
        Markers:{...}
    }
}
let pluto= {
    layer:{
        ...
        Markers:{...}
    }
}

现在我如何切换到不同的地图(带有单独的标记)是

function setMap(selectedMap, htmlElement, ifSub = false) {
        if (currentMap != selectedMap) {
            map.removeLayer(window[currentMap].Layer)
            map.addLayer(window[selectedMap].Layer)

            currentMap = selectedMap

        }
    }

通过一个按钮(并在启动时),我给 pluto 上的一些标记设置了 class(可以说是“已访问”),这会为它们更改 css。

然而,当我将地图更改为地球并返回冥王星时 来自冥王星的标记“忘记”了他们首先有一个 class。 我如何将 css 与标记一起存储?并在调用 map.addLayer(...) 时添加回标记?

这里的问题是,当从地图中删除标记时,其图标图像也会被删除,因此您手动添加的任何 classes 或 CSS 样式都会丢失。下次再次将标记添加到地图时,将创建一个新图像。

如果您只需要对标记图标的外观进行简单的更改,您可以创建一组具有不同图像的图标和您需要的 classes,然后将标记设置为使用合适的图标.您可以使用 myMarker = new L.Marker(latlngs, {icon: myIcon}) 设置适当的初始图标,然后使用 mymarker.setIcon(myOtherIcon) 更改它。 Marker 会记住它被设置为使用哪个图标,即使它已从地图中删除并再次添加回来。 Leaflet 文档包含一个 tutorial on using custom icons,它展示了如何创建您自己的图标。如果您希望它们具有不同的 classes,请在创建它们时使用 className 选项。

如果您需要能够独立添加和删除 classes,那么简单地使用具有不同 classes 的图标可能行不通。但是,我们可以扩展标记的定义以添加 class 设置功能。以下代码基于 L.Markersource code 创建一个新的 class of L.ClassedMarker 对象:

L.ClassedMarker = L.Marker.extend({
  options: {
    classes: []
  },
  addClass: function(className) {
    if(this.options.classes.indexOf(className) === -1) {
      this.options.classes.push(className);
    }
    this._initIcon();
  },
  getClasses: function() {
    return this.options.classes;
  },
  removeClass: function(className) {
    var index = this.options.classes.indexOf(className);
    if(index > -1) {
      this.options.classes.splice(index, 1);
    }
    this._initIcon();
  },
  _initIcon: function() {
    L.Marker.prototype._initIcon.apply(this, null);
    for(let cls of this.options.classes) {
      L.DomUtil.addClass(this._icon, cls);
    }
  }
});
L.classedMarker = function(latLng, options) {
  return new L.ClassedMarker(latLng, options);
}

我们可以像使用普通 Marker 一样使用 ClassedMarker,但是在创建它时,我们可以指定一个(可选的)class 列表来添加到图标:

var myMarker = L.classedMarker(latlngs, {classes: ["new"]}).addTo(map);

您还可以在创建 ClassedMarker 后添加或删除 classes:

myMarker.removeClass("new");
myMarker.addClass("visited");

ClassedMarker 会记住您添加了哪些 classes,无论您是在地图上添加或删除它,还是更改标记的图标。您可以使用 myMarker.getClasses() 检查添加了哪些 classes。请注意,这只是 returns 您的自定义 classes,而不是 Leaflet 内部使用的,或者使用标记图标的 className 选项设置的。

该代码通过在 ClassedMarker 的选项而不是图标中维护一个 classes 列表来工作。每次需要更新图标时,它都会调用原始 L.Marker class 中的 _initIcon() 代码,然后使用 L.DomUtil.addClass() 应用存储的 class 名称到新的图标图像。