как я могу увеличить процент на 1% всего одним щелчком мыши

#javascript #html

Вопрос:

Я хочу, чтобы процент увеличивался на 1% каждую секунду всего одним нажатием кнопки «Увеличить» и то же самое для кнопки «уменьшить», но с уменьшением процента на -1% каждую секунду. Прямо сейчас у меня правильный код, но для достижения 100% требуется несколько кликов по кнопке увеличения, мне нужен всего один клик, и он будет увеличиваться на 1% каждую секунду, пока не достигнет 100%, и уменьшаться на 1% каждую секунду, если нажать кнопку уменьшения.

 function value() {
  var x = document.getElementById("number").getAttribute("aria-precentnow");
  return x;
}

function rvalue(precent) {
  document.getElementById("number").setAttribute("aria-precentnow", precent);
  document.getElementById("number").setAttribute("style", "width: "   precent   "%;");
  document.getElementById("number").innerHTML = (precent   "%");
}


function increase() {
  var i = value();
  if (i <= 100) {
    i  ;
    rvalue(i);
  } else {
    alert("Congrats you hit 100%");
  }
}

function decrease() {
  var x = value();
  rvalue(x - 1);
}

function reset() {
  var y = value();
  rvalue(y = 0);
} 
 <div class="container">
  <div class="progress">
    <div id="number" class="progress-bar" role="number" style="width: 0%;" aria-precentnow="0" aria-precentmin="0" aria-precentmax="100" id="number">0</div>
  </div>
  <br>
  <button onclick="increase()">Increase</button>
  <button onclick="decrease()">Decrease</button>
  <button onclick="reset()">Reset</button>
  <p id="precent"> </p>
</div> 

Комментарии:

1. Гюнтер, извини, моя правка переписала твою, я не собирался

2. Не беспокойтесь, я думаю, что я снова отредактировал по ошибке на самом деле.

Ответ №1:

Вам нужно установить progressBar атрибут вместе с textContent .

 const progressBar = document.querySelector('.progress > .progress-bar');

const getProgress = () => parseInt(progressBar.getAttribute('aria-precentnow'), 10);

const setProgress = (val) => {
  progressBar.setAttribute('aria-precentnow', val);
  progressBar.textContent = `${val}%`;
  progressBar.style.width = `${val}%`
}

const addProgress = (amount) => {
  const val = getProgress()   amount;
  setProgress(val > 100 ? 100 : val < 0 ? 0 : val);
};

window.increase = () => addProgress(1);
window.decrease = () => addProgress(-1);
window.reset = () => setProgress(0); 
 .progress-bar {
  background: #F88;
  text-align: right;
  padding: 0.25em;
} 
 <div class="container">
  <div class="progress">
    <div id="number" class="progress-bar" role="number" style="width: 0%;" aria-precentnow="0" aria-precentmin="0" aria-precentmax="100" id="number">0%</div>
  </div>
  <br>
  <button onclick="increase()">Increase</button>
  <button onclick="decrease()">Decrease</button>
  <button onclick="reset()">Reset</button>
  <p id="precent"> </p>
</div> 

Ответ №2:

Рекурсивная функция тайм-аута, вызывающая ваше существующее увеличение/уменьшение, должна сделать свое дело:

Функции increaseAuto / decreaseAuto здесь вызовут обычное увеличение/уменьшение, но также повторно вызовут себя снова через 1 секунду.

Вы также можете использовать clearTimeout(autoTimeout) в любом месте (например, при достижении 100% или сбросе), чтобы остановить автоматическое прогрессирование.

 function increaseAuto() {
  // Clear any existing timeout (As this would carry on when you try to switch direction)
  clearTimeout(autoTimeout)
  // Run the normal increase function
  increase()
  // Set a timeout to trigger this again in 1 second
  autoTimeout = setTimeout(increaseAuto, 1000)
}
 

Полный пример:

 // - New code
// This variable is used to keep track of the timeout
var autoTimeout = null

// This function will trigger the increase, but also call itself again after 1 second
function increaseAuto() {
  clearTimeout(autoTimeout)
  increase()
  autoTimeout = setTimeout(increaseAuto, 1000)
}

// This is the same as the above, but for decrease
function decreaseAuto() {
  clearTimeout(autoTimeout)
  decrease()
  autoTimeout = setTimeout(decreaseAuto, 1000)
}

// - Existing code with minor clearTimeouts added:
function value() {
  var x = document.getElementById("number").getAttribute("aria-precentnow");
  return x;
}

function rvalue(precent) {
  document.getElementById("number").setAttribute("aria-precentnow", precent);
  document.getElementById("number").setAttribute("style", "width: "   precent   "%;");
  document.getElementById("number").innerHTML = (precent   "%");
}

function increase() {
  var i = value();
  if (i <= 100) {
    i  ;
    rvalue(i);
  } else {
    alert("Congrats you hit 100%");
    // Once you hit 100% stop ticking upwards
    clearTimeout(autoTimeout)
  }
}

function decrease() {
  var x = value();
  rvalue(x - 1);
}

function reset() {
  var y = value();
  rvalue(y = 0);
  clearTimeout(autoTimeout)
} 
 <div class="container">
  <div class="progress">
    <div id="number" class="progress-bar" role="number" style="width: 0%;" aria-precentnow="0" aria-precentmin="0" aria-precentmax="100" id="number">0%</div>
  </div>

  <br>
  <button onclick="increaseAuto()">Increase</button>
  <button onclick="decreaseAuto()">Decrease</button>
  <button onclick="reset()">Reset</button>

  <p id="precent"> </p>

</div> 

Ответ №3:

Я хочу, чтобы процент увеличивался на 1% каждую секунду всего одним нажатием кнопки «Увеличить» и то же самое для кнопки «уменьшить», но с уменьшением процента на -1% каждую секунду.

Попробуйте это:

 let direction = 1, current = 0, timer = 0, progressElm = document.getElementById("number")

// updates the dom
function update() {
  progressElm.setAttribute("aria-precentnow", current);
  progressElm.setAttribute("style", "width: "   current   "%");
  progressElm.innerHTML = current   "%";
}

// sets direction
function increase() {
  direction = 1
  current  = direction // if you want increase on click too
  if (!timer) run()
}

// ...
function decrease() {
  direction = -1
  current  = direction // if you want decrease on click too
  if (!timer) run()
}

// resets the state
function reset() {
  clearInterval(timer)
  direction = 1
  current = 0
  timer = 0
  update()
}

// runs the timer/logic
function run() {
  clearInterval(timer)
  timer = setInterval(() => {
    current  = direction
    update()

    if (current >= 100) decrease()
    if (current <= 0) increase()
  }, 1000)
} 
 <div class="container">
  <div class="progress">
    <div id="number" class="progress-bar" role="number" style="width: 0%;" aria-precentnow="0" aria-precentmin="0" aria-precentmax="100" id="number">0%</div>
  </div>

  <br>
  <button onclick="increase()">Increase</button>
  <button onclick="decrease()">Decrease</button>
  <button onclick="reset()">Reset</button>

  <p id="precent"> </p>

</div>