Search code examples
javascriptdom-eventshere-api

Nokia Here hijacks window's DOMMouseScroll events


Nokia Here hijacks window's DOMMouseScroll events.

I register the event like this:

window.addEventListener('DOMMouseScroll', 
                        function(){console.log('mouse wheel')}, 
                        true);

But it is never triggered when using the mouse wheel over the Here Map.

My guess is that Here Map's API catches the event before my handler does and then cancels the event.

How to deal with this situation?


Solution

  • Depending on what functionality you need from the map, you can either disable map interaction entirely or just disable mouse scroll.

    Option 1 - Disable map interaction

    When you create the map, you can add components to specify which functionality you want:

    map = new nokia.maps.map.Display(mapContainer, {
      center: [40.664167, -73.838611],
      zoomLevel: 15,
      components: [
        new nokia.maps.map.component.Behavior()
      ]
    });
    

    The nokia.maps.map.component.Behavior component loads the default set of interactions (zoom.MouseWheel, zoom.DoubleClick, etc). See http://developer.here.com/javascript-apis/documentation/maps/topics_api_pub/nokia.maps.map.component.Behavior.html for more.

    If you don't include that component, the map won't capture any of those things.

    Option 2 - Disable only MouseScroll

    If you do want some of the behaviours but not the mousescroll, you can load the Behavior component then remove the specific one you don't want:

    map = new nokia.maps.map.Display(mapContainer, {
      center: [40.664167, -73.838611],
      zoomLevel: 15,
      components: [
        new nokia.maps.map.component.Behavior()
      ]
    });
    
    map.removeComponent(map.getComponentById("zoom.MouseWheel"));
    

    This would leave the double-click zooming, dragging and the rest of the map functionality but not catch the scroll event.

    Option 3 - Custom zoomMouseWheel

    If you need the map's zoom scroll functionality and still want the mousescroll events, you can first disable the built-in behaviour (option 2 above) then implement your own scroll listener:

    function zoomMouseWheel(e) {
      var newZoomLevel;
      var toX = e.x;
      var toY = e.y;
      if (e.wheelDelta) {
          newZoomLevel = map.zoomLevel+e.wheelDelta;
      } else if (e.detail) {
          newZoomLevel = map.zoomLevel+(e.detail * -1);
      }
      map.setZoomLevel(newZoomLevel, "default", toX, toY)
    };
    
    mapContainer.addEventListener('mousewheel', zoomMouseWheel, true);
    mapContainer.addEventListener('DOMMouseScroll', zoomMouseWheel, true);
    
    document.addEventListener('mousewheel', function(){console.log('mouse wheel')}, true);
    document.addEventListener('DOMMouseScroll', function(){console.log('mouse wheel')}, true);
    

    NOTE: Tested in Chrome & Firefox on OS X, it may be necessary to modify the wheelDelta calculation for other browsers