Google Maps API v3: разрешить контекстное меню по умолчанию в пользовательском OverlayView - PullRequest
0 голосов
/ 11 ноября 2019

У меня есть карта с пользовательскими наложениями (на основе https://developers -dot-devsite-v2-prod.appspot.com / maps / Documentation / javascript / examples / overlay-popup ).

Пользовательский оверлейный контент включает ссылку / якорный тег и Я хотел бы позволить пользователю щелкнуть правой кнопкой мыши ссылку и выбрать «Открыть в новой вкладке» , однако правые щелчки отменяютсякарта, и я не могу понять, как предотвратить такое поведение.

Если вы сравните образец пользовательского наложения, связанного выше, с Информационным окном по умолчанию https://developers -dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/infowindow-simple вы можете заметить, что пользовательское наложение НЕ показывает контекстное меню при щелчке правой кнопкой мыши по тексту «Hello World», тогда как информационное окно НЕ показываетконтекстное меню. В инструментах разработки я заметил обработчик событий в информационном окне, который каким-то образом позволяет контекстное меню (удаление этого обработчика останавливает появление контекстного меню), однако, так как это в минимизированном коде карт Google, я не могу понять его.

Я пробовал следующее:

google.maps.event.addListener(map, 'rightclick', function (e) {
    var event = e.ya;
    var element = event.target;
    if (element.nodeName === "A") {
        event.stopImmediatePropagation();
        event.stopPropagation();
        return true;
    }
});

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

Я также попытался установить preventMapHitsFrom на пользовательскомоверлей (https://developers.google.com/maps/documentation/javascript/reference/overlay-view#OverlayView.preventMapHitsAndGesturesFrom),, из-за которого вышеприведенный код больше не срабатывает, но контекстное меню по-прежнему отсутствует.

Мне также удалось самостоятельно подключить обработчик событий (извините за jQuery):

$(document).on("contextmenu", ".map-popup__link", function (e) {
    e.stopImmediatePropagation();
    return true;
});

Но опять-таки не уверен, как предотвратить отмену события. Я также пытался инициировать новое событие для того же элемента, но это просто создает цикл (очевидно) без решения проблемы.

На основена https://stackoverflow.com/a/7414594/1397352 Я изменил функцию Popup.prototype.onAdd на

Popup.prototype.onAdd = function () {
    this.getPanes().floatPane.appendChild(this.containerDiv);

    this.getPanes().overlayMouseTarget.appendChild(this.containerDiv);

    // set this as locally scoped var so event does not get confused
    var me = this;

    // Add a listener - we'll accept clicks anywhere on this div, but you may want
    // to validate the click i.e. verify it occurred in some portion of your overlay.
    google.maps.event.addDomListener(this.containerDiv, 'contextmenu', function () {
        google.maps.event.trigger(me, 'contextmenu');
    });
};

Точка останова в обработчике событий срабатывает, но опять контекстное меню не отображается.

Кто-нибудь получил этоработать с пользовательскими оверлеями?

1 Ответ

0 голосов
/ 14 ноября 2019

Благодаря комментарию MrUpsidown мне удалось найти решение в (заархивированной) информационной библиотеке: https://github.com/googlemaps/v3-utility-library/blob/master/archive/infobox/src/infobox.js#L231

Похоже, я был близок в первой попытке, но должен был установить event.cancelBubble = true;

Окончательное решение:

Popup.prototype.onAdd = function () {
    this.getPanes().floatPane.appendChild(this.containerDiv);

    // This handler allows right click events on anchor tags within the popup
    var allowAnchorRightClicksHandler = function (e) {
        if (e.target.nodeName === "A") {
            e.cancelBubble = true;
            if (e.stopPropagation) {
                e.stopPropagation();
            }
        }
    };
    this.contextListener_ = google.maps.event.addDomListener(this.containerDiv, "contextmenu", allowAnchorRightClicksHandler);
};

Popup.prototype.onRemove = function () {
    if (this.contextListener_) {
        google.maps.event.removeListener(this.contextListener_);
        this.contextListener_ = null;
    }
    if (this.containerDiv.parentElement) {
        this.containerDiv.parentElement.removeChild(this.containerDiv);
    }
};

см. https://developers -dot-devsite-v2-prod.appspot.com / карты / документация / javascript / examples / overlay-popup для оставшейся части всплывающего кода

...