Event to notify when map has moved positioned within browser... does one exist??

1761
11
07-02-2013 06:47 PM
PeterLen
Occasional Contributor
I am using the ArgGIS Javascript API v3.5.  I have a map displayed in my browser, but it does not take up the full page.  One of the things I have is to place a map marker where the user clicks on the map.  All is good there.  But, if the user does something that moves the map's position within the browser window, say by scrolling or by moving a splitter, the map marker is displayed in a different place than where the mouse click took place.  I believe this is because the screen to coordinate mapping got out of sync when the map was repositioned.  I saw that there is a map event called onReposition but that is not getting triggered during the cases I mentioned.  I need to find an event that will get triggered so that I can call something like resize() (or something else) to get the screen to coordinate mapping back into sync.

Does anyone know if a map event exists that will help me or do I need to deal with events outside of the map to track when to call a map.resize()??

Thanks - Peter
0 Kudos
11 Replies
TimCollyer
Occasional Contributor
There are various events that I think would work. Probably try "onExtentChange".

Are you adding your "map marker" as a map graphic or something else? A graphic should stay on the same location on the map however you manipulate the map.
0 Kudos
PeterLen
Occasional Contributor
Tim - Thanks for the response.  The onExtentChange does not help because the extent itself is not changed.  This is not a zoom or a pan.  This is simply when the map is shifted to a different location within the browser window.  The extent (boundary coordinates) are unchanged.  Yes, I am adding my markers as graphics to the graphics layer.  Some years ago I was working with the OpenLayers javascript mapping API and had this same type of issue.  I found that when the map is loaded, there is some mapping that maps the X/Y location of the map within the browser to actual coordinates on the map.  If the map moves (thus the map has a new X/Y location in the browser) the mapping is thrown off.  The distance between where you click on the map and where the map marker is displayed is the same as how far the map was shifted within the browser.  There just doesn't seem to be a map event that gets triggered when this happens.  I though the onReposition would be the one, but it doesn't get triggered.

- Peter
0 Kudos
JeffJacobson
Occasional Contributor III
Is the marker an ArcGIS JS API graphic? I thought a graphic would move along with the map.

Can you make a jsfiddle demonstrating the behavior you described?
0 Kudos
PeterLen
Occasional Contributor
Jeff - Not sure if my explanation was confusing.  I am not talking about a map marker (graphic) ALREADY being on the map and then when the map gets shifted the map marker is displayed at a different location.  That is not the problem I am encountering (you are correct in that the marker will always stay displayed at the location it was added).  The issue is if the map gets shifted and then I click on the map to add my marker (the intent is to display the marker where I clicked on the map), the marker gets added to a location just outside of where I clicked the map (the distance depends on how far the map has shifted).

So, for example, when the page first loads and I click the map, a marker is displayed at the point where I clicked the map.  If I then do something that makes the map shift its location within the browser (say by moving the scroll bar if one exists), and then click the map, my map marker is displayed at some point NEAR where I clicked but not at the point that I clicked on.
0 Kudos
JonathanUihlein
Esri Regular Contributor
Hi Peter,

I tried to recreate your issue and cannot.

Can you make a jsfiddle with your code that shows the issue?
http://jsfiddle.net/
0 Kudos
PeterLen
Occasional Contributor
Jon,

Thanks for the reply.  I tried to add the example code to jsfiddle but for whatever reason it didn't load the ArcGIS Javascript API file, so the map was not loaded.  The full code is not that much so I will paste it to this reply.  This will show the problem.  The 3 steps will be listed on the page.

-----------------------------------------

<html>
  <head>
     <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/esri/css/esri.css">
     <style>
      
       html, body, #map {
         height:500px;
         width:100%;
         margin:0;
         padding:0;
       }
     </style>

     <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/"></script>

     <script>
var MAP_OBJ;

        dojo.require("esri.map");
        function init() {
            MAP_OBJ = new esri.Map("map", {
                basemap: "topo",
                center: [-122.45, 37.75],
                zoom: 10,
                sliderStyle: "small"
            });
            dojo.connect(MAP_OBJ, "onLoad", function () {
                dojo.connect(MAP_OBJ, "onClick", addMapMarker);
                dojo.connect(MAP_OBJ, "onResize", onMapResize);
  dojo.connect(MAP_OBJ, "onReposition", onMapReposition);
            });
        }

//
function addMapMarker(evt) {
            var mp = evt.mapPoint;
            var symbol = new esri.symbol.SimpleMarkerSymbol(
                         esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE,
                         10,
                         new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID,
                         new dojo.Color("red"), 1),
                         new dojo.Color("blue"));

            var graphic = new esri.Graphic( mp, symbol);

            MAP_OBJ.graphics.add(graphic);

}
        dojo.ready(init);
//
function collapseDiv() {
    var div = document.getElementById("divTop");
    div.style.display = "none";
}
//
function displayDiv() {
    var div = document.getElementById("divTop");
    div.style.display = "block";
}
function onMapResize(evt) { alert("RESIZE"); }
function onMapReposition(evt) { alert("REPOSITION"); }
     </script>

  </head>
  <body> <form>
     <div id="divTop" style="padding:10px;border:2px solid black; height:100px">
        <input type="button" value="Collapse" onClick="javascript:collapseDiv()">
<br/>Step 1: Click on the map and see marker placed where click occurred.
<br/>Step 2: Click the Collapse button and click on the map again. Marker is not displayed at click location.
     </div>
     <div id="map"></div>
     <div id="divBottom" style="padding:10px;border:2px solid black; height:100px">
        <input type="button" value="Display" onClick="javascript:displayDiv()">
<br/>Step 3: Click the Display button and click on the map again.
     </div>
  </form></body>
</html>

-----------------------------------------
0 Kudos
ReneRubalcava
Frequent Contributor
Jsfiddle isn't working for me right now, but I put it into Plunker and sure enough I can see the behavior you are talking about.
http://plnkr.co/Zz7GD3DawoJnlT9UIAUH

I don't see an easy fix off the top of my head, but if I manually do a resize in the collapse function the points show up as they should.

 function collapseDiv() {
   MAP_OBJ.resize();
   var div = document.getElementById("divTop");
   div.style.display = "none";
 }


Not the solution you are probably looking for since in other cases I can't find a way to capture when the map has moved, but could probably be hacked in.

Nice catch on this one.
0 Kudos
PeterLen
Occasional Contributor
Rene - Great, thanks for the reply and testing it.  I am glad you were able to see what my original problem is.  My post was to see if anyone knew of a map event that would be triggered during this type of situation (ie, the map being repositioned within the browser).  I was hoping that there was an event but wanted to verify via this posting that an event either did or did not exist.  If one did not exist, that is fine.  I will just have to track the event via other non-map items and do the MAP_OBJ.resize() (like you did).  It would just be easier if there was a map event.

Thanks - Peter
0 Kudos
ReneRubalcava
Frequent Contributor
I did some digging around on how to capture when a dom element has been repositioned and there doesn't seem to be an easy way to do it. I tried listeneng for "scroll", which I thought might do it, but no luck.

Maybe if you have the map in a container, you can listen for that containers resize event.
0 Kudos