Контекстное меню листовки не отображается на маркере

#javascript #leaflet #contextmenu

#javascript #листовка #contextmenu

Вопрос:

Я использую эту библиотеку в своем Java-проекте. Я включаю его вместе с некоторыми другими плагинами листовки в свой jsp файл. В скрипте я сталкиваюсь с очень странной и кажущейся невозможной ошибкой. Если я инициализирую карту с помощью контекстного меню, отобразится контекстное меню карты. Но аналогичная вещь не происходит с маркером. Мои маркеры не являются статическими и создаются только при нажатии кнопки, как видно из этой функции:

 function handleItem(item) {

    var tbody=$('#traffic-data').find('tbody');

    var row=document.createElement("tr");
    row.setAttribute('class','danger');
    row.setAttribute("from-lat",item.fromLat);
    row.setAttribute("from-lng",item.fromLng);
    row.setAttribute("to-lat",item.toLat);
    row.setAttribute("to-lng",item.toLng);

    var cenLat=(item.fromLat item.toLat)/2;
    var cenLng=(item.fromLng item.toLng)/2;

    var cell=document.createElement("td");
    geocodeService.reverse().latlng([cenLat,cenLng]).run(function(error, result) {
        if (!error){
            cell.innerHTML=result.address.Match_addr;
        }
        cell.onclick=function(){
            focusJam(cenLat,cenLng);
        };
        row.appendChild(cell);

        cell=document.createElement("td");
        cell.innerHTML=new Date();
        row.appendChild(cell);

        cell=document.createElement("td");
        cell.innerHTML=item.velocity;
        row.appendChild(cell);

        cell=document.createElement("td");
        row.appendChild(cell);

        cell=document.createElement("td");
        cell.innerHTML=Math.round(L.latLng(item.fromLat,item.toLng)
            .distanceTo(L.latLng(item.toLat,item.toLng)));
        row.appendChild(cell);

        cell=document.createElement("td");
        row.appendChild(cell);

        cell=document.createElement("td");
        var action=document.createElement('span');
        action.setAttribute('class','glyphicon glyphicon-ok-sign');
        action.onclick=function(){
            row.removeAttribute('class');
            row.setAttribute('class','info');
            L.marker(L.latLng(cenLat,cenLng),{icon:customDefaultIcon},{
                contextmenu: true,
                contextmenuWidth: 140,
                contextmenuItems: [{
                    text: 'Marker item',
                    index: 0
                }, {
                    separator: 'Marker item',
                    index: 1
                }]
            }).addTo(map);
        };
        cell.append(action);
        action=document.createElement('span');
        action.setAttribute('class','glyphicon glyphicon-trash');
        action.onclick=function(){
            row.remove();
        };
        cell.append(action);
        row.appendChild(cell);

        tbody.append(row);
    });

};
  

Как ни странно, эта инициализация маркера:

 L.marker(L.latLng(cenLat,cenLng),{icon:customDefaultIcon},{
                contextmenu: true,
                contextmenuWidth: 140,
                contextmenuItems: [{
                    text: 'Marker item',
                    index: 0
                }, {
                    separator: 'Marker item',
                    index: 1
                }]
            }).addTo(map);
  

было совершенно напрасно, отображается только маркер, но не контекстное меню при нажатии правой кнопкой мыши. Но если я инициализирую так:

 L.marker(L.latLng(cenLat,cenLng),{
                contextmenu: true,
                contextmenuWidth: 140,
                contextmenuItems: [{
                    text: 'Marker item',
                    index: 0
                }, {
                    separator: 'Marker item',
                    index: 1
                }]
            },{icon:customDefaultIcon}).addTo(map);
  

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

Ответ №1:

L.Marker Конструктор принимает один набор опций:

 var m1 = L.marker(latlng, options);       // good
var m2 = L.marker(latlng, opts1, opts2);  // wrong
  

Так что это неправильно:

 var opts1 = {
            contextmenu: true,
            contextmenuWidth: 140,
            contextmenuItems: [{
                text: 'Marker item',
                index: 0
              }, {
                separator: 'Marker item',
                index: 1
              }]
            };

var opts2 = {icon:customDefaultIcon};

L.marker(L.latLng(cenLat,cenLng), opts1, opts2).addTo(map);
  

И это правильно:

 var opts = {
            contextmenu: true,
            contextmenuWidth: 140,
            contextmenuItems: [{
                text: 'Marker item',
                index: 0
              }, {
                separator: 'Marker item',
                index: 1
              }],
            icon: customDefaultIcon
            };

L.marker(L.latLng(cenLat,cenLng), opts).addTo(map);
  

Будьте осторожны, чтобы не запутаться при настройке набора параметров, особенно если некоторые из ваших параметров представляют собой массивы словарей. Создавайте вспомогательные переменные по мере необходимости, чтобы сделать ваш код более читаемым, например:

 var menuitems = [{
                  text: 'Marker item',
                  index: 0
                }, {
                  separator: 'Marker item',
                  index: 1
                }];

var opts = {
            contextmenu: true,
            contextmenuWidth: 140,
            contextmenuItems: menuitems,
            icon: customDefaultIcon
            };

L.marker(L.latLng(cenLat,cenLng), opts).addTo(map);