jQuery扩展和停止setInterval()

时间:2011-07-25 09:51:13

标签: javascript jquery

我有以下jQuery扩展名:

var particleTimer = 0;
jQuery.fn.particleEmitter = function (num, wid, hei, rad, tme, rep) {
   particleTimer = setInterval(function() {
      //appends elements...
   }, 500);
};

jQuery.stopParticleEmitter = function () {
  clearInterval(particleTimer); //this doesn't stop it...
}

但是clearInterval()似乎不起作用......

以下是我完整代码的小提琴:http://jsfiddle.net/neuroflux/wtJFj/3/

请注意,“粒子”实际上不会移动,因为它需要文档宽度...

但是计时器应该清除onMouseout ......而不是......

3 个答案:

答案 0 :(得分:3)

正如前面提到的那样,只记录你设置的所有计时器,所以当你想要杀死它们来处理它们时,这里几乎没有修改你的代码

http://jsfiddle.net/qRheY/

它并不完美,但是......它可以正常工作(删除正弦,因为它导致我的浏览器出错)

P.S。如果你想要你可以将处理程序保存在一个数组中,并在一个循环中销毁它们

http://jsfiddle.net/bnePt/

答案 1 :(得分:2)

就实际setInterval而言,您的代码看起来很好,如果您只在任何给定时间运行一个粒子发射器,我看不出它会起作用的任何理由。

我说的是“一次一个”,因为跳出来的第一件事就是你假设没有人使用你的插件会多次打电话给你particleEmitter,因为你正在使用一个变量来处理句柄。

我会通过返回来维持处理调用者的责任,而不是自己跟踪它。

jQuery.fn.particleEmitter = function (num, wid, hei, rad, tme, rep) {
   return setInterval(function() {
      //appends elements...
   }, 500);
};

jQuery.stopParticleEmitter = function(timerHandle) {
  if (timerHandle !== 0) {
      clearInterval(timerHandle);
  }
  return 0;
}

particleEmitter中退出句柄意味着你无法链接,但是A)你的原文不支持链接(除非需要返回任何其他内容,约定是返回this插件功能,用于链接);并且B)并不总是需要支持链接,而不是如果你有充分的理由返回不同的值。

旁注:我从上面的限制函数返回0,因为我倾向于在我的代码中使用这个成语:

myHandleVar = jQuery.stopParticleEmitter(myHandleVar);

显然,这种风格可能不符合您的口味。 : - )

两个发射器的

Live working example,呼叫者跟踪句柄:

HTML:

<div id="container1">
  <input type='button' class='start' value='Start 1'>
  <input type='button' class='stop'  value='Stop 1'  disabled>
  <p class="target"></p>
</div>
<div id="container2">
  <input type='button' class='start' value='Start 2'>
  <input type='button' class='stop'  value='Stop 2'  disabled>
  <p class="target"></p>
</div>

JavaScript的:

jQuery(function($) {
  var handles = {};

  $("#container1, #container2").each(function() {
    var $this = $(this);
    $this.find(".start").click(startClick);
    $this.find(".stop").click(stopClick);
  });

  function startClick() {
    var container = $(this).closest('div[id^="container"]'),
        id = container[0] && container[0].id;
    if (id) {
      handles[id] = container.find(".target").particleEmitter();
      this.disabled = true;
      container.find(".stop")[0].disabled = false;
    }
      }

  function stopClick() {
    var container = $(this).closest('div[id^="container"]'),
        id = container[0] && container[0].id;
    if (id) {
      handles[id] = $.stopParticleEmitter(handles[id]);
      this.disabled = true;
      container.find(".start")[0].disabled = false;
    }
  }

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});

更新:您在下面询问了如何停止所有。这很简单,只需跟踪你发出的句柄(live example):

(function() {
  // Our current set of outstanding handles
  var handles = {};

  // Hook up our emitter function
  jQuery.fn.particleEmitter = function (num, wid, hei, rad, tme, rep) {
    var target = this,
        handle;

    // Start this interval timer
    handle = setInterval(function() {
      $("<span>click </span>").appendTo(target);
    }, 500);

    // Store the handle in a map
    handles[handle] = handle;

    // Return the handle
    return handle;
  };

  // Our "stop" function
  jQuery.stopParticleEmitter = function(timerHandle) {
    if (timerHandle !== 0) {
      // Clear the timer
      clearInterval(timerHandle);

      // Remove the handle from our "outstanding" list
      delete handles[timerHandle];
    }

    // Return a value the caller can use to clear our their
    // handle variable.
    return 0;
  }

  // Our "stop all" function
  jQuery.stopAllParticleEmitters = function() {
    var handle;
    for (handle in handles) {
      if (handles.hasOwnProperty(handle)) { // Largely unnecessary check
        clearInterval(handle);
      }
    }
    // Clear our outstanding handles. There's no race
    // condition here, JavaScript on browsers is single-threaded.
    handles = {};
  };
})();

请注意所有这些都包含在函数中,因此handles变量对我们的插件是私有的。

答案 2 :(得分:1)

这个小提琴奏效:http://jsfiddle.net/7WzzH/

也许是因为您在声明fn功能时忘了stopParticleEmitter

以下是更正后的版本

$.fn.stopParticleEmitter = function () {
  clearInterval(particleTimer);
}

修改

当然不行。你在for循环中进行了12次(!)迭代,所以使用你的函数你将只清除最后一个间隔,你将有11个继续工作。你必须至少使用数组。或者将rep设置为1,它会起作用。

在此处rep == 1http://jsfiddle.net/wtJFj/5/