0

I would appreciate a little help. Right now I'm learning Openlayers 3. I want to bind a click event to several map objects within a for loop.

When I do it like this, the event is only applied to the last map object within the for loop:

for(var i = 0; i < $('.easymap').length;i++) { // [...] var elem = map[i]; elem.on('singleclick',function(evt){ elem.getView().setCenter(evt.coordinate); }); }

I think I already found out that this a typical problem where a "closure" is needed. However, I didn't find out how to do this yet.

The following (stupid) workaround, which works only for a given number of maps and produces many lines of redundant code, is only a temporary solution:

// solve later (make dynamic, learn how to use closures... ) if($('#easymap1').length && $('#easymap1').hasClass('addpost')) map[0].on('singleclick',function(evt){ /*alert(ol.coordinate.format(evt.coordinate, '{x}')+' '+ol.coordinate.format(evt.coordinate, '{y}'));*/ map[0].getView().setCenter(evt.coordinate); }); if($('#easymap2').length && $('#easymap2').hasClass('addpost')) map[1].on('singleclick',function(evt){ map[1].getView().setCenter(evt.coordinate); }); if($('#easymap3').length && $('#easymap3').hasClass('addpost')) map[2].on('singleclick',function(evt){ map[2].getView().setCenter(evt.coordinate); }); if($('#easymap4').length && $('#easymap4').hasClass('addpost')) map[3].on('singleclick',function(evt){ map[3].getView().setCenter(evt.coordinate); }); if($('#easymap5').length && $('#easymap5').hasClass('addpost')) map[4].on('singleclick',function(evt){ map[4].getView().setCenter(evt.coordinate); });

So, does can anyone tell my how to integrate this into a proper for loop? Thank you.

Best regards joschi81

winnewoerp
  • 161
  • 6

2 Answers2

0

ol.View won't fire events on singleclick. so if you're going to use evt.coordinate you need to be sure you're getting an ol.MapBroswerEvent.

it's not clear where your array of ol.Maps is coming from, but once you have your maps in an array, (it appears) the loop should be written as:

for (var i = 0; i < mapArray.length; i++) {
  var targetMap = mapArray[i];
  targetMap.on('singleclick',function(evt){
    // this event is sent by the map
    targetMap.getView().setCenter(evt.coordinate);
  });
}

hope that's helpful.

lazaruslarue
  • 318
  • 2
  • 14
  • Hi, thanks for your answer. I'm sorry, I didn't get exactly what you mean here. 'singleclick' is working pretty well, the only problem is that I don't manage to bind it to several maps within the for loop. – winnewoerp May 23 '15 at 10:15
0

The problem is, that the handler is created in every iteration of your for loop, which means, that in the last iteration, the handler's reference to elem corresponds to the last map. So even if the handler is fired by click on another map, it sets center to the map which is stored in variable elem. But the singleclick event contains the map that was clicked, so you can easily do this:

for (var j = 0, jj = maps.length; j < jj; j++) {
  var elem = maps[j];
  elem.on('singleclick',function(evt){
    evt.map.getView().setCenter(evt.coordinate);
  });   
}

or, even better (to only define the handler once):

var onMapClick = function(evt) {
  evt.map.getView().setCenter(evt.coordinate);
}

for (var j = 0, jj = maps.length; j < jj; j++) {
  var elem = maps[j];
  elem.on('singleclick', onMapClick);   
}

see fiddle: http://jsfiddle.net/Kenny806/v5k97oye/

Hope this helps

Kenny806
  • 595
  • 4
  • 8
  • Hi Kenny806, thanks for your answer. This seems to be exactly what I need. I will check that out asap. – winnewoerp May 23 '15 at 10:17
  • Implemented your solution, works perfectly. Didn't need the separate function yet, as I don't need it more than once. Also, I used 'click' and not 'singleclick'. There's no 'doubleclick' event used for my maps, so 'click' is sufficient - and the delay of the 'singleclick' event is a bit annoying. – winnewoerp May 24 '15 at 06:32