简体   繁体   中英

Run function once per event burst with jQuery

I'm using jQuery to listen to DOMSubtreeModified event, and then execute a function. What I need is a way to only run a function once per event burst. So in this case, the event will only run after 1 second, and again after 3 seconds. What is the best way to do this?

jQuery

$(function(){

    setTimeout(function(){
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
    },1000);

    setTimeout(function(){
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
    },3000);

    $('#container').bind('DOMSubtreeModified',function(){
        console.log('event');
        functionToRun();
    });

});

HTML

<div id="container"></div>



The setTimeout function are there just to emulate my problem. I need a solution without changing the setTimeout code. The problem I'm having is that I get burst of DOMSubtreeModified events, and I need to get only one per burst.

Alternate method, which will control the rate of any function.

// Control the call rate of a function.
//  Note that this version makes no attempt to handle parameters
//  It always induces a delay, which makes the state tracking much easier.
//    This makes it only useful for small time periods, however.
//    Just clearing a flag after the timeout won't work, because we want
//    to do the the routine at least once if was called during the wait period.
throttle = function(call, timeout) {
  var my = function() {
    if (!my.handle) {
      my.handle = setTimeout(my.rightNow, timeout);
    }
  };
  my.rightNow = function() {
    if (my.handle) {
      clearTimeout(my.handle);
      my.handle = null;
    }
    call();
  };
  return my;
};

Solved it myself.

$(function(){

    setTimeout(function(){
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
    },1000);

    setTimeout(function(){
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
    },1100);

    setTimeout(function(){
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
        $('#container')[0].innerHTML = 'test';
    },3000);

    addDivListener();

 });

 function addDivListener() {
    $('#container').bind('DOMSubtreeModified',function(){
        functionToRun();
        $(this).unbind('DOMSubtreeModified');
        setTimeout(addDivListener,10);  
    });
 }

 function functionToRun(){
    console.log('event');
 }

This prints out event 3 times in the Firebug console, and is accurate down to 100 ms.

This seems to be what you're looking for:

$(
  function()
  {
    setTimeout 
    (
      StartWatching,
      1000
    );
  }
);

function StartWatching()
{
  $('#container')
     .bind(
            'DOMSubtreeModified',
            function()
            {
              console.log('event');
              StopWatchingAndStartAgainLater();
            }
          );
}

function StopWatching()
{
  $('#container')
      .unbind('DOMSubtreeModified');
}

function StopWatchingAndStartAgainLater()
{
  StopWatching();
  setTimeout
  (
    StartWatching,
    3000
  );
}

This enforces the following flow:

Document.Ready
Create DOM watching event after one second
On event, turn off event and recreate it after three seconds, rinse, repeat

try using one() handler

documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM