У меня есть листовка с LineString.

// a GeoJSON LineString
var geojson = {
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [[-101.123, 40.2500], [-101.123, 40.2503]]
  }
};

// create map and add json
var map = L.map('map');
var geojsonLayer = new L.GeoJSON(geojson).addTo(map);
map.fitBounds(geojsonLayer.getBounds())

// add popup for the line
geojsonLayer.eachLayer(function (layer) {
  var popup = L.popup();
  popup.setContent('text');

  layer.bindPopup(popup);
  layer.on('click mouseover', function () {
    layer.openPopup();
  });
});

Когда я над ним, всплывающее окно открывается в центре LineString.

Как я могу открыть его в позиции курсора?

Вот простой рабочий пример: http://jsfiddle.net/wuu8Lv2t/1/

1
Hugo H 7 Янв 2017 в 17:17

3 ответа

Лучший ответ

Не позволяйте слою открывать всплывающее окно, вместо этого используйте openOn(map), устанавливая положение с координатами из события e.latlng

// add popup for the line
geojsonLayer.eachLayer(function (layer) {
  var popup = L.popup();
  popup.setContent('text');
  layer.bindPopup(popup);

  layer.on('mouseover', function (e) {
    var popup = e.target.getPopup();
    popup.setLatLng(e.latlng).openOn(map);
  });

  layer.on('mouseout', function(e) {
     e.target.closePopup();
  });

  layer.on('mousemove', function (e) {
    e.target.closePopup();
    var popup = e.target.getPopup();
    popup.setLatLng(e.latlng).openOn(map);
  });
});

Обратите внимание, что в вашем вопросе есть ошибка: вы не можете использовать переменную layer в обработчике событий, вы должны использовать e.target (см. doc ).

4
YaFred 7 Янв 2017 в 15:39

Принятый ответ (@YaFred) довольно хорош, главное в функции обновления layer.on('mousemove'.... Однако, как написано, закрытие и открытие всплывающего окна при каждом перемещении мыши заставляет его мерцать. Вместо этого в layer.('mousemove... вам нужна только строка, которая обновляет местоположение:

// add popup for the layer
geojsonLayer.eachLayer(function (layer) {
  var popup = L.popup();
  popup.setContent('text');
  layer.bindPopup(popup);

  layer.on('mouseover', function (e) {
    var popup = e.target.getPopup();
    popup.setLatLng(e.latlng).openOn(map);
  });

  layer.on('mouseout', function(e) {
     e.target.closePopup();
  });

  // update popup location
  layer.on('mousemove', function (e) {
    popup.setLatLng(e.latlng).openOn(map);
  });
});
1
JMers 1 Мар 2019 в 00:45

Вот ответ от Пер Лиедман, сопровождающий Leaflet:

Вы можете достичь этого, создав новое всплывающее окно и добавив его в нужное место, вместо того, чтобы связывать его. Поскольку всплывающее окно может быть открыто другими способами, кроме щелчка мышью, оно не может знать, где его открывать.

Вот соответствующий код:

// a GeoJSON LineString
var geojson = {
  "type": "Feature",
  "geometry": {
    "type": "LineString",
    "coordinates": [[-101.123, 40.2500], [-101.123, 40.2503]]
  }
};

// create map and add json
var map = L.map('map');
var geojsonLayer = new L.GeoJSON(geojson).addTo(map);
map.fitBounds(geojsonLayer.getBounds())

// add popup for the line
geojsonLayer.eachLayer(function (layer) {

  layer.on('click mouseover', function (e) {
    var popup = L.popup()
        .setLatLng(e.latlng)
        .setContent('text')
        .openOn(map);
  });
});

Смотрите здесь для измененного примера: http://jsfiddle.net/uwdnvfy6/

1
Hugo H 9 Янв 2017 в 08:19