[GIS] OpenLayers 4 hover popup delay

event listenerjavascriptopenlayers

I added a function to display a popup on hover to the feature layer but it doesn't work very well.

Here my code:

map.on('pointermove', function(evt) {
  if (evt.dragging) {
    return;
  }

  var info = $('#info');
  info.html("");
  var pixel = map.getEventPixel(evt.originalEvent);
  var feature = map.forEachLayerAtPixel(pixel, function(feature) { return true; }, null, function(layer) { return layer === pmfeatlayer; });
  var viewResolution = map.getView().getResolution();
  var coordinate = evt.coordinate;
  url = pmfeatlayer.getSource().getGetFeatureInfoUrl(coordinate, viewResolution, projection, {'INFO_FORMAT': 'text/html'});

  if (feature && url) {

    info.css({
      left: pixel[0] + 'px',
      top: pixel[1] + 'px'
    });
//    setTimeout(function() {
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", url, true);
    xhttp.send();
    xhttp.onreadystatechange = function (aEvt) {
      if (xhttp.readyState == 4 && xhttp.status == 200) {

          var parser = new window.DOMParser();
          var res = parser.parseFromString(xhttp.responseText, "text/xml");
          var myitems = res.getElementsByTagName('item');

          if(res.getElementsByTagName('item').length != 0){
            info.html("<div class='hoverPopup'>" + hover(xhttp.responseText) + "</div>").delay( 1000 ).fadeIn( 400 );
          } else {
            info.html("");
          }

       } // end if 4 && 200
     }; // end onreadystatechange
 //}, 1000);
   } // end if (feature && url)
 }); // end pointermove

As you can see I'm using map.on('pointermove'… But it's not the exact event, What can I use to detect that the cursor is above the feature layer and it's not moving, for example, .5 seconds?

I tried to add a delay function but still, it doesn't work properly, it made a lot of requests and the popup display buggy due to the delay and the cursor can be on other parts of the map at the time is displayed.

Best Answer

You can try a debounce or throttle function to delay the calls for the popup.

A very simple way could look like this:

var stillMoving = [];
function delayPopup() {
    stillMoving.push(true);          // add my call to array

    setTimeout(function() {
        stillMoving.shift();         // remove my call from array

        // check if more calls are pending
        // if yes stop propagation
        if ( stillMoving[ 0 ] ) {
            return;
        }
        else {
            // load the popup here
            loadPopup();
        }
    }, 500);
}