0

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

我创建了两个回调函数funcstep. 我想创建另一个回调函数,每秒钟x从内部调用一次rangeListener

有任何想法吗?

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

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>

4

1 回答 1

0

油门部分

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

  • 将标志设置为false
  • 在您的节流函数中,如果标志设置为,则不要执行任何操作true
  • 否则,将其设置为true并执行您的功能
  • 完成后,将标志重置为false, 以允许以后调用

区间部分

如果你想每秒执行一个函数X,你最好的选择是使用setTimeoutor setInterval。但是,有多种方法可以做到这一点,并且根据您的使用情况,您可能更喜欢使用其中一种。例如,使用以下代码:

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>

于 2018-04-11T20:27:08.517 回答