How to respond to a Javascript event only if it is fired once and then not fired again during some time period?

Add a timeout, that runs your code 500ms after the event fires, each time the event fires clear the timeout and create a new one.

eg.

google.maps.event.addListener(map, 'bounds_changed', (function () {
    var timer;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(function() {
            // here goes an ajax call
        }, 500);
    }
}()));

There is a really good approach available on unscriptable.com:

Function.prototype.debounce = function (threshold, execAsap) {
    var func = this, // reference to original function
        timeout; // handle to setTimeout async task (detection period)
    // return the new debounced function which executes the original function 
    // only once until the detection period expires
    return function debounced () {
        var obj = this, // reference to original context object
            args = arguments; // arguments at execution time
        // this is the detection function. it will be executed if/when the 
        // threshold expires
        function delayed () {
            // if we're executing at the end of the detection period
            if (!execAsap)
                func.apply(obj, args); // execute now
            // clear timeout handle
            timeout = null;
        };
        // stop any current detection period
        if (timeout)
            clearTimeout(timeout);
        // otherwise, if we're not already waiting and we're executing at the 
        // beginning of the waiting period
        else if (execAsap)
            func.apply(obj, args); // execute now
        // reset the waiting period
        timeout = setTimeout(delayed, threshold || 100);
    };
}

This would let you do:

// call the function 200ms after the bounds_changed event last fired:
google.maps.event.addListener(map, 'bounds_changed', (function() {
  // here goes an ajax call
}).debounce(200));

// call the function only once per 200ms:
google.maps.event.addListener(map, 'bounds_changed', (function() {
  // here goes an ajax call
}).debounce(200,true));

If you prefer to not augment the Function.prototype there is a standalone function debounce(func, threshold, execAsap) available on the blog post.


google suggests using another listener ...

google.maps.event.addListener(map, 'idle', showMarkers);

quote "Note that you could listen to the bounds_changed event but it fires continuously as the user pans; instead, the idle will fire once the user has stopped panning/zooming." /quote

see

http://code.google.com/apis/maps/articles/toomanymarkers.html#gridbasedclustering