如何在范围输入上限制requestFrameAnimation?

时间:2018-04-11 17:16:15

标签: javascript range debounce

我有一个简单的范围输入,我想每隔几秒钟返回一次该值。

我创建了两个回调函数funcstep。我想创建另一个回调函数,从xrangeListener

每隔class Test{ rangeListener(range, func, step) { range.addEventListener("change", function () { func(range.value); }); let listener = function () { window.requestAnimationFrame(function () { step(range.value); }); }; range.addEventListener("mousedown", function () { listener(); range.addEventListener("mousemove", listener); }); range.addEventListener("mouseup", function () { range.removeEventListener("mousemove", listener); }); range.addEventListener("keydown", listener); } } let test = new Test(); test.rangeListener(document.querySelector(".range"), (value) => { document.querySelector(".value").innerHTML = value; }, (step)=> { document.querySelector(".step").innerHTML = step; });秒调用一次

有什么想法吗?

编辑:根据评论进行编辑。

<input type="range" class="range" min="1" max="100" value="1">

<div class="value">0</div>
<div class="step">0</div>
[0, "we break dance not hearts by Short Stack is my ringtone.... i LOVE that !!!.....\n"]
[1, "I want to write a . I think I will.\n"]
[2, "@va_stress broke my twitter..\n"]
[3, "\" &quot;Y must people insist on talking about stupid politics on the comments of a bubblegum pop . Sorry\n"]
[4, "aww great  &quot;Picture to burn&quot;\n"]
[5, "@jessdelight I just played ur joint two s ago. Everyone in studio was feeling it!\n"]
[6, "http://img207.imageshack.us/my.php?image=wpcl10670s.jpg her s are so perfect.\n"]
[7, "cannot hear the new  due to geographic location. i am geographically undesirable. and tune-less\n"]
[8, "\" couples in public\n"]
[9, "damn wendy's commerical got that damn  in my head.\n"]
[10, "i swear to cheese &amp; crackers @zyuuup is in Detroit like every 2 months &amp; i NEVER get to see him!  i swear this blows monkeyballs!\n"]
[11, "\" getting ready for school. after i print out this\n"]

1 个答案:

答案 0 :(得分:0)

节流部分

限制函数调用的一种简单方法是使用标志(布尔变量)。它的工作原理如下:

  • 将标记设置为false
  • 在您的限制功能中,如果标志设置为true
  • ,请不要执行任何操作
  • 否则,将其设置为true并执行您的功能
  • 完成后,将标记重置为false,以便以后调用

间隔部分

如果您想每X秒执行一次功能,最好选择使用setTimeoutsetInterval。但是,有多种方法可以执行此操作,并且根据您的使用情况,您可能更喜欢使用其中一种方法。例如,使用以下代码:

setInterval(myFunc, 5000);

您的功能将在执行前等待5秒钟。

如果您希望第一次执行立即发生,您可以执行此操作(在此处使用IIFE):

(function myInterval(){
    myFunc();
    setTimeout(myInterval, 5000);
})();

结果,包含您的代码

我在下面修改了您的代码以包含这些更改:

class Test {
  rangeListener(range, options) {
    /*
     * This flag will be set to true when we are waiting
     * for the next AnimationFrame, and back to false
     */
    let throttling = false;
    let timer;

    /*
     * Functions
     */
    const changeListener = () => {
      if (!options.onChange) return;
      options.onChange(range.value);
    };

    const stepListener = () => {
      if (!options.onStep || throttling) return;
      throttling = true;

      window.requestAnimationFrame(() => {
        options.onStep(range.value);
        throttling = false;
      });
    };

    const intervalFunc = (isInitialization = false) => {
      if (!options.onInterval) return;
      options.onInterval(range.value);
      if (!isInitialization) {
        timer = setTimeout(intervalFunc, options.delay || 500);
      }
    };

    /*
     * Event listeners
     */
    range.addEventListener("change", changeListener);

    range.addEventListener("mousedown", () => {
      clearTimeout(timer);
      intervalFunc();
      stepListener();
      range.addEventListener("mousemove", stepListener);
    });

    range.addEventListener("mouseup", () => {
      // Execute it once more to get the last value
      intervalFunc();
      clearTimeout(timer);
      range.removeEventListener("mousemove", stepListener);
    });

    range.addEventListener("keydown", stepListener);

    /*
     * Values initialization
     */
    changeListener();
    stepListener();
    intervalFunc(true);
  }
}

let test = new Test();

const setHTML = (selector, value) => {
  document.querySelector(selector).innerHTML = value;
};

test.rangeListener(document.querySelector(".range"), {
  onChange: (value) => setHTML(".value", value),
  onStep: (value) => setHTML(".step", value),
  onInterval: (value) => setHTML(".delayed", value),
  delay: 300
});
<input type="range" class="range" min="1" max="100" value="1">

<div>onChange: <span class="value">0</span></div>
<div>onStep: <span class="step">0</span></div>
<div>onInterval: <span class="delayed">0</span></div>