Изменение ширины div с помощью setinterval

У меня есть этот код с CSS-анимацией:

@keyframes progress-bar {
  0% {
    width: 0;
  }
  50% {
    width: 100%;
  }
  100% {
    width: 0;
  }
}

.box {
  position: relative;
  height: 3px;
  margin-top: 20px;
  background: transparent;
}

.line {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  background: red;
  -webkit-animation: progress-bar 6s ease-in infinite alternate forwards;
  animation: progress-bar 6s ease-in infinite alternate forwards;
}
<div class = "box">
  <div class = "line"></div>
</div>

Это пример ссылки на коды и ящик: ссылка

Это позволяет мне бесконечно заполнять div.line за три секунды, а затем снова скрывать ее ширину за три секунды.

Я хочу реализовать в Vanila JS ту же функциональность, используя setInterval. Я понимаю, что мне нужно использовать setInterval, цикл и получить ширину, используя clientwidth. Но все мои попытки либо сразу очищают setInterval, либо не работают. Помогите пожалуйста найти оптимальное решение, спасибо.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот версия JS — нам все еще нужно НЕКОТОРОЕ CSS.

Я просто УСТАНАВЛИВАЮ ширину и использую пару тройных чисел, чтобы увеличивать или уменьшать ее.

const line = document.querySelector('.line');
let width = 0;
let growing = true;
const intervalDuration = 30; 
const totalDuration = 6000; // total duration of the animation in milliseconds
const maxSteps = totalDuration / intervalDuration; // number of steps in the animation cycle
const increment = 100 / maxSteps; // calculate increment once
const interval = setInterval(() => {
  // Increment or decrement the width based on the growing state
  width += growing ? increment : -increment;

  // Switch direction if limits are reached
  growing = (growing && width >= 100) || (!growing && width <= 0) ? !growing : growing;

  line.style.width = `${width}%`; 
}, intervalDuration);
.box {
  position: relative;
  height: 3px;
  margin-top: 20px;
  background: transparent;
}

.line {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  background: red;
}
<div class = "box">
  <div class = "line"></div>
</div>

Привет! Действительно хорошее решение! Можете ли вы объяснить мне больше о интервалеDuration и maxSteps? Почему вы выбрали 30 и что означает maxSteps? Спасибо!

yanballas 22.04.2024 09:07

30 миллисекунд — хорошее число для примерно 30 кадров в секунду. Я получил 6 секунд из вашей CSS-анимации. totalDuration/intervalDuration показывает, сколько шагов нам нужно, чтобы разделить 100%-ную длину. Но спасибо за указание, я изменил код, чтобы использовать 100/maxSteps для задания приращения/уменьшения.

mplungjan 22.04.2024 09:49
Ответ принят как подходящий

Вы также можете использовать другую альтернативу с переменной CSS и JavaScript, как показано ниже. Если вы хотите достичь 100% с 0% за 3 секунды, вам нужно установить интервал 30 мс.

const line = document.querySelector('.line')
const root = document.querySelector(':root')
let lineWidth = 0
let increment = true


function incrementWidth(){
    if (lineWidth<100 && increment){
        lineWidth+=1
        root.style.setProperty("--width", `${lineWidth}%`)
        if (lineWidth===100){ 
            increment=false
        }
    }
    if (lineWidth > 0 && !increment){
        lineWidth-=1
        root.style.setProperty("--width", `${lineWidth}%`)
        if (lineWidth===0){ increment=true}
    }
}

let interval_ID = setInterval(()=>{
    incrementWidth()
},30)
  
  :root{
    --width: 0%;
  }

  .box {
    position: relative;
    height: 3px;
    margin-top: 20px;
    background: transparent;
  }
  
  .line {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--width);
    height: 100%;
    background: red;
  }
    <div class = "box">
        <div class = "line"></div>
    </div>

Привет Чувак! Удивительно и легко – молодец! Я до сих пор не могу понять, почему вы выбираете шаг 30 мс?

yanballas 22.04.2024 09:13

@yanballas, спасибо и добро пожаловать! 30 мс — это время, необходимое для достижения шага в 1 % на индикаторе выполнения из 100 %, чтобы вы достигли 100 % за 100 * 30 мс = 3000 мс = 3 с, как вы и хотели. Наслаждайтесь кодированием!

Mehdi 22.04.2024 09:57

Другие вопросы по теме