以编程方式为 JQuery 滑块设置动画

Programmatically animating a JQuery Slider

我正在尝试以编程方式 change/animate 一个 JQuery 滑块。在此示例中,有两个数组:一个用于要更改的值,一个用于更改之间的持续时间。如果您查看控制台,您会看到值随着相应的持续时间而变化。但是,滑块在达到最终值之前不会移动。我也在尝试更新 sliderValue span 元素。同样,它仅随最后一个值而变化。有关演示,请参阅 JSFiddle 示例(控制台日志)。滑块应从 100 开始并使用持续时间数组向上滑动到 105。

let valueArray = [101, 102, 103, 104, 105]
let durationArray = [800, 600, 550, 700, 300]
$("#sliderValue").html(100)
$("#slider").slider({
  value: 100,
  min: 0,
  max: 200,
  step: 1,
  slide: function(event, ui) {
    $("#sliderValue").html(ui.value);
  }
});

function pausecomp(millis, value) {
  var date = new Date();
  var curDate = null;
  do {
    curDate = new Date();
  }
  while (curDate - date < millis);
  console.log(value)
  $('#sliderValue').html(value)
  $("#slider").slider("option", "value", value);
}

function startSlider() {
  $("#sliderValue").html(100);
  $("#slider").slider("option", "value", 100);
  for (var i = 0; i < valueArray.length; i++) {
    pausecomp(durationArray[i], valueArray[i]);
  }
}

HTML:

  <h1>Setting Slider Programmatically</h1>
  <div id="slider"></div>
  <p>Slider Value<span id="sliderValue"></span></p>
  <input type="button" value="Start Slider Animation" onclick="startSlider()">

Jsfiddle example

do..while 循环在 'waiting' 期间持续运行,将 CPU(一个核心)利用到 100%。 jQuery 显然在内部使用了异步逻辑,但是 while 循环不允许 JS event loop 触发它,只有在它完成之后。

所以你也必须使用异步逻辑。例如,从经典的 setTimeout 到更现代的 async/await 使用一点 'sleep' 辅助函数。

let valueArray = [101, 102, 103, 104, 105]
let durationArray = [800, 600, 550, 700, 300]
$("#sliderValue").html(100)
$("#slider").slider({
  value: 100,
  min: 0,
  max: 200,
  step: 1,
  slide: function(event, ui) {
    $("#sliderValue").html(ui.value);
  }
});

waitUntil = 0;

function pausecomp(millis, value) {
  setTimeout(function() {
    console.log(value)
    $('#sliderValue').html(value)
    $("#slider").slider("option", "value", value);
  }, waitUntil += millis)
}

function startSlider() {
  console.clear()
  $("#sliderValue").html(100);
  $("#slider").slider("option", "value", 100);
  waitUntil = 0;
  for (var i = 0; i < valueArray.length; i++) {
    pausecomp(durationArray[i], valueArray[i]);
  }
}

function sleep(millis) {
  console.log('Sleep ' + millis)
  return new Promise(resolve => setTimeout(resolve, millis));
}

async function pausecompAsync(millis, value) {
  await sleep(millis);
  console.log(value)
  $('#sliderValue').html(value)
  $("#slider").slider("option", "value", value);
}

async function startSliderAsync() {
  console.clear()
  $("#sliderValue").html(100);
  $("#slider").slider("option", "value", 100);
  for (var i = 0; i < valueArray.length; i++) {
    await pausecompAsync(durationArray[i], valueArray[i]);
  }
  console.clear()
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css" />

<div id="slider"></div>

<p>Slider Value<span id="sliderValue"></span></p>

<input type="button" value="Start Slider Animation" onclick="startSlider()">
<input type="button" value="Start Slider Animation using async/await/Promise" onclick="startSliderAsync()">