disabling map interactions until clicked

261
2
08-13-2019 05:56 PM
JohnMDye
Regular Contributor

Very simple map app. 

map.js

require([
      "esri/Map",
      "esri/views/MapView"
    ], function(Map, MapView) {

    var map = new Map({
      basemap: "streets-navigation-vector"
    });

    var view = new MapView({
      container: "mapDiv",
      map: map,
      center: [-98.5420115, 39.2241764], // longitude, latitude
      zoom: 3
    });
  });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

index.html

<head>
  <link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/themes/light/main.css">
</head>
<style>
  html, body, mapDiv {
    padding: 0;
    margin: 0;
    min-height: 25rem;
    width: 100vw;
}
</style>
<body>
  <div id="mapDiv"></div>
  // Lots of other content...

  <script src="https://js.arcgis.com/4.12/"></script>
  <script src="map.js"></script>
</body>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

So you've got a 100% wide map div, which is not very tall at the top of the page, Then a bunch of content underneath it. Think OpenData UI. Very much like that. 

Now, when a user lands on the page, they hit their mouse-wheel and want to scroll the page. Well, the map starts zooming because the mapDiv is at the top of the page and 100% wide, so odds are very good that the user's cursor is on top of the map, giving it focus. 

Okay, let's disable that...

map.js

require([
      "esri/Map",
      "esri/views/MapView"
    ], function(Map, MapView) {

    var map = new Map({
      basemap: "streets-navigation-vector"
    });

    var view = new MapView({
      container: "mapDiv",
      map: map,
      center: [-98.5420115, 39.2241764], // longitude, latitude
      zoom: 3
    });
    // Don't zoom map when user scrolls mouse - they probably want to scroll the page
    view.on("mouse-wheel", function(event) {
      view.stopPropogation();
    });
    
  });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This solves the problem but creates two additional issues.

1. Now, the user can't zoom the map with their mouse wheel at all. Also, this does nothing for touch devices where the user might swipe to try to scroll the page. In that case, swiping on the map pans it, another unintended interaction. 

2. When the user uses their mouse wheel to scroll, since they are likely hovering over the map when using their mouse wheel (given its prominent size and position on the page), the page doesn't scroll because the event is being sent to the mapDiv which is stopping the propagation to prevent the map from zooming and the mouse-wheel event never gets sent to the page body to scroll the page.

The assumption is that the user wants to scroll the page when they interact with the mouse-wheel, and if they want to interact with the map, they'll give it focus by clicking or tapping on it.

So given the above assumption, how does one disable all map interactions until the viewer expressly clicks/taps on the map to give it focus, and when that happens enable all of the interactions methods and then turn them back off again when the map loses focus by the user clicking or tapping outside of the mapDiv?

Tags (2)
0 Kudos
2 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

John,

  Here is the solution for the mouse wheel. Not sure about the touch portion though.

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Intro to MapView - Create a 2D map - 4.12</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

  <link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.12/"></script>

  <script>
    require(["esri/Map", "esri/views/MapView"], function (Map, MapView) {
      var map = new Map({
        basemap: "streets"
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 4,
        center: [15, 65] // longitude, latitude
      });
      let wheelEvtHandler = view.on("mouse-wheel", function (event) {
        event.stopPropagation();
        window.scrollBy(0, 30);
      });
      view.on("click", function (evt) {
        wheelEvtHandler.remove();
      });
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <div id="lipsum">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc velit quam, pharetra tempor nibh et, consectetur
      laoreet orci. Phasellus rutrum risus id magna malesuada, nec ultrices eros suscipit. Pellentesque lobortis in ante
      iaculis sagittis. Donec laoreet tincidunt dapibus. Phasellus interdum eros at nisi tempus pellentesque nec ac mi.
      Donec et tortor nec risus fermentum posuere. Vivamus rhoncus quam nec molestie congue. Integer sed mollis magna.
      Quisque non libero quis velit placerat iaculis.
    </p>
    <p>
      Fusce sed diam at felis fermentum mattis. Fusce eu ornare sapien, sit amet euismod risus. Aliquam feugiat nibh
      quis nulla consequat, vitae elementum augue dapibus. Vestibulum eu nisi ullamcorper, porta mauris in, faucibus
      diam. Curabitur tempus euismod convallis. Vestibulum interdum convallis nisl, ac commodo diam mollis ut. Ut
      bibendum dui id urna viverra tincidunt. Praesent id justo sed justo congue feugiat. Nullam eget velit magna. Nulla
      vitae turpis quis nunc vehicula mattis nec quis neque. Donec ultricies leo nibh, in accumsan nunc mollis finibus.
      Cras malesuada sapien quis euismod venenatis. Pellentesque mattis viverra tellus, at ultricies augue efficitur
      nec. Suspendisse volutpat aliquam condimentum. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
      per inceptos himenaeos. Suspendisse sagittis diam quis mauris convallis auctor.
    </p>
    <p>
      Quisque condimentum placerat purus, in posuere felis sagittis sed. Sed at nibh sem. Sed iaculis enim nec mauris
      fermentum, in ornare lorem consectetur. Mauris blandit justo a urna blandit, quis eleifend enim porttitor. Nullam
      mattis ipsum eu lacus elementum venenatis. Mauris vitae neque tortor. Integer auctor suscipit sodales. Nam non leo
      a sapien euismod blandit. Aliquam ullamcorper gravida ex, nec convallis purus blandit at. Quisque eget dolor non
      erat dictum sollicitudin. Suspendisse tincidunt egestas purus non elementum. Sed blandit at ligula nec feugiat.
    </p>
    <p>
      Nunc euismod nunc ac neque tincidunt volutpat. Sed tincidunt, orci et rutrum sodales, elit nibh eleifend ligula,
      non feugiat tortor nulla eget felis. Phasellus fermentum ante vestibulum quam rutrum, efficitur blandit diam
      porttitor. Aenean porta turpis velit, quis dapibus nulla blandit sit amet. Nunc non sodales dolor. Proin hendrerit
      libero nec vulputate auctor. Maecenas id nibh eget ante egestas sodales. Morbi molestie, quam eget auctor tempor,
      sem lorem sollicitudin ipsum, sed blandit magna tellus ac ex. Nulla venenatis dapibus suscipit. Nullam malesuada
      convallis magna, et consectetur leo facilisis a. Nunc facilisis ex in tortor malesuada maximus. Pellentesque nibh
      sapien, faucibus vitae metus quis, interdum viverra dui. Quisque a congue libero. Ut eget velit velit.
    </p>
    <p>
      Curabitur eu blandit augue. Vestibulum malesuada a tellus vel dapibus. Vestibulum ac metus enim. Suspendisse
      efficitur scelerisque maximus. Morbi pulvinar justo a nibh convallis, vitae dapibus nulla pretium. Phasellus vitae
      sapien egestas orci hendrerit tincidunt a sed ligula. Praesent vulputate dui vel metus tristique maximus.
      Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas vehicula mauris
      eu dolor accumsan venenatis. Ut dui diam, dignissim ac orci in, tristique accumsan ipsum. Aenean sapien dui,
      ullamcorper vel lacinia luctus, cursus sed lectus.
    </p>
  </div>
</body>

</html>
JohnMDye
Regular Contributor

Thanks Robert, I'll give this a try tonight. If anyone else has the other half of the answer, it would be much appreciated. I'm thinking the most reliable way to handle the nuances of this might be the old switcharoo technique, using an PNG or JPG of the map on page load and then swapping it out with the interactive mapDiv when the user clicks on the image. I feel like there should be a more elegant and better way the handle this though.

0 Kudos