Select to view content in your preferred language

How do I synchronize multiple map events?

859
1
07-13-2017 01:37 AM
ParkSeungHyun
Deactivated User

I want to sync four map screens.

However, binding an event to a map object as follows behaves abnormally.

How do I sync all of my maps?

var map1 = new esri.Map("div1","basemapId");

var map2 = new esri.Map("div2","basemapId");

var map3 = new esri.Map("div3","basemapId");

var map4 = new esri.Map("div4","basemapId");

var obj1 = map1.on('extent-change',initExtent);

var obj2 = map2.on('extent-change',initExtent);

var obj3 = map3.on('extent-change',initExtent);

var obj4 = map4.on('extent-change',initExtent);

function initExtent(e){

   if(e.target.id ==='div1'){

      map2.setExtent(e.extent);

      map3.setExtent(e.extent);

      map4.setExtent(e.extent);

   }

   else{

      map1.setExtent(e.extent);

  }

}

0 Kudos
1 Reply
DavidBlanchard
Esri Contributor

The reason for the erratic behavior is event recursion, which is essentially an infinite loop of events calling themselves over and over again.

Remember that within your initExtent function, when you set the extent programatically, this will cause an extent-change event to be dispatched on each of those maps. This in turn calls the initExtent function again, which cause new extent-change events, and the cycle continues forever (or until your browser kills the script).

The trick to fix this is to determine whether an update is actually needed inside the initExtent function or whether this is just a result of programatic extent changes. Here's one way you could approach this with 3 maps:

  var extentChanged = function(newExtent) {
       var changed = false;
    if (lastExtent === undefined ||
     newExtent.xmin !== lastExtent.xmin ||
     newExtent.ymin !== lastExtent.ymin ||
     newExtent.xmax !== lastExtent.xmax ||
     newExtent.ymax !== lastExtent.ymax) {
         changed = true;
    }
    lastExtent = newExtent;
    return changed;
  }
  
  var synchronizeMaps = function(event) {
       if (extentChanged(event.extent)) {
         lastExtent = event.extent;
      
      var id = event.target.id;

      if (id != "map1") {
        map1.setExtent(event.extent);
      }

      if (id != "map2") {
        map2.setExtent(event.extent);
      }

      if (id != "map3") {
        map3.setExtent(event.extent);
      }
     }
  };

I've made a fully functional demo in JSFiddle: Multiple Synchronized Maps - JSFiddle