Search code examples
javascriptcontextmenuhere-apiheremaps

How can I dismiss a HERE Maps context menu programmatically?


I have a HERE Maps map displayed on a simple webpage with a multiselect dropdown and a couple of buttons. I'm using the contextmenu event to show a context menu on right-click, like so:

var map = new H.Map(
    document.getElementById('mapContainer'),
    maptypes.raster.normal.map,
    {
        zoom: 12,
        center: { lat: -33.81, lng: 150.78 },
        pixelRatio: window.devicePixelRatio || 1,
        engineType: H.map.render.RenderEngine.EngineType.P2D
    }
);

...

// an H.map.Polygon object we prepared earlier
polygonObject.addEventListener("contextmenu", handleContextMenu)

...

function handleContextMenu(evt) {
    // Don't do anything if the map itself is right-clicked/long-pressed
    if (evt.target === map) {
        return;
    }

    if (evt.target instanceof H.map.Polygon) {
        // Polygon-specific context menu items
        evt.items.push(new H.util.ContextItem({ label: "ABC123" }));
        evt.items.push(H.util.ContextItem.SEPARATOR);
        evt.items.push(new H.util.ContextItem({ label: "Do something", callback: function () { doSomething(evt) } }));
    }
}

This works fine, displays a context menu when a polygon object is right-clicked, and dismisses itself if somewhere else on the map is tapped. However, the context menu doesn't dismiss if the user clicks or interacts with another element on the page outside the map.

I wasn't able to find any documentation on how to achieve this behaviour, and the example that HERE Maps uses also doesn't dismiss the context menu if somewhere outside the map is clicked. Is there any way to dismiss the context menu on a map, either programmatically or automatically if another page element is interacted with?


Solution

  • It's a little bit hacky, but you can manually remove the context menu from the DOM by finding a div with the h_context_menu class in the page, and removing it. This may have some unintended side effects with the UI class, but seems to work OK from my brief testing.

    Using JQuery:

    $("div.h_context_menu").remove()
    

    Using ES6:

    document.querySelector("div.h_context_menu").remove()
    

    Using vanilla JavaScript (compatible with Internet Explorer):

    var el = document.querySelector("div.h_context_menu");
    el.parentNode.removeChild(el);