Javascript 将 ID 分配给传单中的标记

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25683871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 21:41:59  来源:igfitidea点击:

Assign ID to marker in leaflet

javascripthtmlcssmapsleaflet

提问by lauWM

So i try to achieve a result as on foursquare: https://foursquare.com/explore?cat=drinks&mode=url&near=Pariswhich is when you clik on a marker on the map, it scrolls through the listed of restaurants on the right -hand side of the screen to the ad hoc restaurant, and highlights it through CSS. Conversely, when you click on the restaurant on the list, it highlights it on the map.

所以我尝试在foursquare上实现结果:https: //foursquare.com/explore?cat =drinks &mode =url &near =Paris 当您点击地图上的标记时,它会滚动浏览右侧的餐厅列表- 屏幕的一侧到临时餐厅,并通过 CSS 突出显示它。相反,当您单击列表中的餐厅时,它会在地图上突出显示它。

I am using skobbler/leaflet. I think I can achieve this by amending dynamically CSS as shown in this example: http://jsfiddle.net/gU4sw/7/+ a scroll to destination script already in place in the page.

我正在使用 skobbler/传单。我想我可以通过修改动态 CSS 来实现这一点,如下例所示:http: //jsfiddle.net/gU4sw/7/+ 滚动到页面中已经存在的目标脚本。

To achieve this however, it looks like I need to assign an ID within the markers (2 markers below):

然而,为了实现这一点,看起来我需要在标记中分配一个 ID(下面有 2 个标记):

var marker = L.marker([52.52112, 13.40554]).addTo(map);
marker.bindPopup("Hello world!<br>I am a popup1.", { offset: new L.Point(-1, -41) }).openPopup();

var marker = L.marker([52.53552, 13.41994]).addTo(map);
marker.bindPopup("Hello world!<br>I am a popup2.", { offset: new L.Point(-1, -41) }).openPopup();

Question is: How can I assign an marker ID to trigger css change in the corresponding element within my html page?

问题是:如何分配标记 ID 以触发 html 页面中相应元素的 css 更改?

My knowledge of JS is very limited, but may be there's a nice and easy solution out there, thx

我对 JS 的了解非常有限,但可能有一个很好且简单的解决方案,谢谢

回答by SkipHyman

I've been looking for a nice way to do this and as far as I can tell there is still no built-in way (using leaflet) to give a marker an ID. I know I'm a bit late to answering this but hopefully it will help others who stumble upon this question. As far as I can tell there are two main issues here:

我一直在寻找一种很好的方法来做到这一点,据我所知,仍然没有内置方式(使用传单)来为标记提供 ID。我知道我回答这个问题有点晚了,但希望它能帮助那些偶然发现这个问题的人。据我所知,这里有两个主要问题:

Problem #1:Unless you save your markers to an object or map, described below, there is no easy programmatic way of accessing them later on. For example - A user clicks something OUTSIDE the map that corresponds to a marker INSIDE the map.

问题 1:除非您将标记保存到对象或地图(如下所述),否则以后没有简单的编程方式来访问它们。例如 - 用户单击地图外部与地图内部标记相对应的内容。

Problem #2:When a user clicks on a marker INSIDE the map, there is no built in way to retrieve the ID of that marker and then use it to highlight a corresponding element or trigger an action OUTSIDE the map.

问题 2:当用户点击地图内的标记时,没有内置的方法来检索该标记的 ID,然后使用它来突出显示相应的元素或触发地图外的操作。

Solutions

解决方案

Using a one or more of these options will help address the issues described above. I'll start with the one mentioned in the previous answer. Here is the working pen, which holds all the code found below.

使用这些选项中的一个或多个将有助于解决上述问题。我将从上一个答案中提到的那个开始。这是工作笔,它包含下面找到的所有代码。

Option #1:Save each marker, using a hardcoded or dynamic ID, inside an object -

选项 #1:使用硬编码或动态 ID 在对象内保存每个标记 -

// Create or retrieve the data
var data = [
    {
      name: 'Bob',
      latLng: [41.028, 28.975],
      id: '2342fc7'
    }, {...}, {...}
];

// Add an object to save markers
var markers = {};

// Loop through the data
for (var i = 0; i < data.length; i++) {
  var person = data[i];

  // Create and save a reference to each marker
  markers[person.id] = L.marker(person.latLng, {
    ...
  }).addTo(map);
}

Similar to the other answer you can now access a single marker by using -

与其他答案类似,您现在可以使用 -

var marker = markers.2342fc7; // or markers['2342fc7']

Option #2:

选项#2:

While leaflet doesn't provide a built-in 'id' option for markers, you can add the an ID to the element directly by accessing ._iconproperty:

虽然传单没有为标记提供内置的“id”选项,但您可以通过访问._icon属性直接将 ID 添加到元素:

// Create and save a reference to each marker
markers[person.id] = L.marker(person.latLng, {...}).addTo(map);

// Add the ID
markers[person.id]._icon.id = person.id;

Now when you handle click events, it's easy as pie to get that marker's ID:

现在,当您处理点击事件时,很容易获取该标记的 ID:

$('.leaflet-marker-icon').on('click', function(e) {
   // Use the event to find the clicked element
   var el = $(e.srcElement || e.target),
       id = el.attr('id');

    alert('Here is the markers ID: ' + id + '. Use it as you wish.')
});

Option #3:

选项#3:

Another approach would be use the layerGroupinterface. It provides a method, getLayer, that sounds like it would be perfect get our markers using an ID. However, at this time, Leaflet does not provide any way to specify a custom ID or name. This issueon Github discusses how this should be done. However you can get and save the auto-generated ID of any Marker (or iLayerfor that matter) like so:

另一种方法是使用layerGroup接口。它提供了一种方法,getLayer听起来像使用 ID 获取我们的标记是完美的。但是,此时 Leaflet没有提供任何方式来指定自定义 ID 或 name。Github 上的这个issue讨论了如何做到这一点。但是,您可以iLayer像这样获取并保存任何标记(或就此而言)的自动生成的 ID :

var group = L.layerGroup()

people.forEach(person => {
    // ... create marker
    group.addLayer( marker );
    person.marker_id = group.getLayerId(marker)
})

Now that we have every marker's ID saved with each backing object in our array of data we can easily get the marker later on like so:

现在我们已经将每个标记的 ID 与数据数组中的每个支持对象一起保存,我们稍后可以轻松地获取标记,如下所示:

group.getLayer(person.marker_id)

See this penfor a full example...

有关完整示例,请参阅这支笔...

Option #4:

选项#4:

The cleanest way to do this, if you have the time, would be to extend the leaflet's marker class to handle your individual needs cleanly. You could either add an id to the options or insert custom HTML into the marker that has your id/class. See the documentationfor more info on this.

如果您有时间,最简洁的方法是扩展传单的标记类以干净地处理您的个人需求。您可以向选项添加 id 或将自定义 HTML 插入具有您的 id/class 的标记中。有关这方面的更多信息,请参阅文档

You can also you use the circleMarkerwhich, in the path options, you will see has an option for className which can be nice for styling groups of similar markers.

您也可以使用circleMarker,在路径选项中,您将看到 className 的一个选项,它可以很好地为相似标记的样式组设置样式。

Styling:

造型:

Almost forgot that your original question was posed for the purpose of styling... simply use the ID to access individual elements:

几乎忘记了您最初的问题是为了造型而提出的……只需使用 ID 来访问单个元素:

.leaflet-marker-icon#2342fc7 { ... }

Conclusion

结论

I'll also mention that layer and feature groups provide another great way to interface with markers. Here is a questionthat discusses this a bit. Feel free to tinker with, or fork either the firstor second penand comment if I've missed something.

我还将提到图层和要素组提供了另一种与标记交互的好方法。这是一个稍微讨论这个问题的问题。如果我遗漏了一些东西,请随意修补或叉出第一支第二支笔并发表评论。

回答by Marko Letic

An easy way to do this is to add all the markers to a list with a unique id.

一种简单的方法是将所有标记添加到具有唯一 ID 的列表中。

var markersObject = {};
markersObject["id1"] = marker1;
markersObject["id2"] = marker2;
markersObject["id3"] = marker3;

If the list of restaurants have a property in the html element of a single restaurant that corresponds to the id of the added marker. Something like:

如果餐厅列表在单个餐厅的 html 元素中具有与添加标记的 id 对应的属性。就像是:

<a href="#" id="singleRestaurantItem" data-restaurantID="id1" data-foo="bar">Click</a>

Then add the click event where you will pass the id of the restaurant (in this case "data-restaurantID") and do something like:

然后添加点击事件,您将在其中传递餐厅的 id(在本例中为“data-restaurantID”)并执行以下操作:

markersObject["passedValueFromTheClickedElement"].openPopup();

This way once you click on the item in the list a markers popup will open indicating where on the map is the restaurant located.

这样,一旦您单击列表中的项目,就会打开一个标记弹出窗口,指示餐厅在地图上的位置。

回答by Slava84

var MarkerIcon = L.Icon.extend({
    options: {
        customId: "",
        shadowUrl: 'leaf-shadow.png',
        iconSize: [64, 64],
        shadowSize: [50, 64],
        iconAnchor: [22, 94],
        shadowAnchor: [4, 62],
        popupAnchor: [-3, -76]
    }
});

var greenIcon = new MarkerIcon({iconUrl: "/resources/images/marker-green.png"}),            
    redIcon = new MarkerIcon({iconUrl: "/resources/images/marker-red.png"}),
    orangeIcon = new MarkerIcon({iconUrl: "/resources/images/marker-orange.png"});

var mymap = L.map('mapid').setView([55.7522200, 37.6155600], 13);

L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    maxZoom: 18,
    id: 'mapbox.streets'
}).addTo(mymap);

// добавить маркер
L.marker([55.7522200, 37.6155600], {customId:"010000006148", icon: greenIcon, title:setMarkerTitle("010000006148")}).addTo(mymap).on('click', markerOnClick);
L.marker([55.7622200, 37.6155600], {customId:"010053166625", icon: redIcon, title: setMarkerTitle("010053166625")}).addTo(mymap).on('click', markerOnClick);

function markerOnClick(e) {
    var customId = this.options.customId;
    document.location.href = "/view/abonents/" + customId;
}

function setMarkerTitle(customId){
    var result = customId;
    result += "\nline2 ";
    result += "\nline3 ";
    return result;
}

回答by Brendan McGill

For my case, I found the best way was to generate and pass a unique ID to L.marker's Options object when I create it.

就我而言,我发现最好的方法是L.marker在创建它时生成唯一 ID 并将其传递给的 Options 对象。

const newMarker = L.marker([lat, lng], { uniqueID })

You can then add this marker to a leaflet layerGroup.

然后,您可以将此标记添加到传单中layerGroup

const newLayerGroup = L.layerGroup().addTo(map);
newLayerGroup.addLayer(newMarker);

You can access the ID with layer.options.uniqueIDThis allows me to find and manipulate the marker later; all I need is Leaflet's .eachLayer()and the uniqueID.

您可以使用此 ID 访问此 ID,layer.options.uniqueID以便我稍后查找和操作标记;我所需要的只是传单.eachLayer()和uniqueID。

My backend (Cloud Firestore) already generates unique document ID's, which makes it super easy to sync my Leaflet map and backend in real-time, rather than rebuilding and remounting the entire layerGroup or refreshing the page.

我的后端 (Cloud Firestore) 已经生成了唯一的文档 ID,这使得实时同步我的 Leaflet 地图和后端变得非常容易,而不是重建和重新安装整个 layerGroup 或刷新页面。

//e.g. a callback which fires whenever a doc has been removed from my db

newLayerGroup.eachLayer((layer) => {
  if (deletedDocID === layer.options.uniqueID) {
    newLayerGroup.removeLayer(layer);
  }
});

回答by Joel Mason

A fairly straight forward and easy way to accomplish creating an array of clickable markers within a leaflet map object is to manipulate the class list of the created marker by adding a custom incremented class name to each marker. Then it is easy to create a listener and know which marker was clicked. By skipping the active one or not, each has a retrievable click event with a reliable ID.

在传单地图对象中完成创建可点击标记数组的一种相当直接且简单的方法是通过向每个标记添加自定义递增类名称来操作所创建标记的类列表。然后很容易创建一个监听器并知道点击了哪个标记。通过跳过或不跳过活动的事件,每个事件都有一个可检索的具有可靠 ID 的点击事件。

  // creates markers, each with a leaflet supplied class
  if (length === 1) {
    for (i = 0; i < parks.length; ++i) {
      if (parks[i].parksNumber !== parks.parksNumber)
        L.marker([parks[i].latitude, parks[i].longitude], {
          icon: parks[i].iconMarker
        }).addTo(mymap);
    }
  }

  // select all of the leaflet supplied class
  let markers = document.querySelectorAll(".leaflet-marker-icon");

  // loop through those elements and first assign the indexed custom class
  for (i = 0; i < markers.length; ++i) {
    markers[i].classList.add("marker_" + parks[i].parksNumber);

    // then add a click listener to each one
    markers[i].addEventListener("click", e => {

      // pull the class list
      let id = String(e.target.classList);

      // pull your unique ID from the list, be careful cause this list could 
      // change orientation,  if so loop through and find it
      let parksNumber = id.split(" ");
      parksNumber = parksNumber[parksNumber.length - 1].replace("marker_", "");

      // you have your unique identifier to then do what you want with
      search_Number_input.value = parksNumber;
      HandleSearch();
    });
  }

回答by Eduards Silins

1.) Lets create Marker with unique id...

1.) 让我们创建具有唯一 ID 的标记...

L.marker([marker.lat, marker.lng],{customID:'some ID',title:marker.title}).on('click', this.markerClick).addTo(mymap);

2.) Go to node_modules@types\leaflet\index.d.ts and add customID?:string;

2.) 转到 node_modules@types\leaflet\index.d.ts 并添加 customID?:string;

export interface MarkerOptions extends InteractiveLayerOptions {
    icon?: Icon | DivIcon;
    title?: string;

    ....

    autoPanSpeed?: number;
    customID:string;
}

3.) In the same file add customID to LeafletMouseEvent

3.) 在同一个文件中添加 customID 到 LeafletMouseEvent

export interface LeafletMouseEvent extends LeafletEvent {
  latlng: LatLng;
  layerPoint: Point;
  containerPoint: Point;
  originalEvent: MouseEvent;
  customID:customID
}

4.) Create customID class

4.) 创建 customID 类

export class customID {
  constructor(customID: string);
  customID: number;
} 

5.) Get your marker id in function

5.) 在函数中获取您的标记 ID

markerClick(e){
  console.log(e.sourceTarget.options.customID)
}

回答by duhaime

Leaflet's className optioncan allow one to add identifiers to objects:

Leaflet 的className 选项可以允许向对象添加标识符:

var onMouseover = function() {
  // returns all members of the specified class
  d3.selectAll(".mySpecialClass")
    .style("opacity", ".1");
};

// add desired class to pointer 
L.circleMarker([46.85, 2.35], {className: "mySpecialClass"})
  .addTo(map).on('mouseover', onMouseover);

// to select the marker(s) with a particular class, just use css selectors
// here's a d3.js solution
d3.selectAll(".mySpecialClass")
  .style("opacity", ".3")