С Новым годом! Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531

Некорректно работает функция sleep

18.02.2025, 12:24. Показов 2408. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Не могу понять в чём дело. Узнал что в JS нет такой функции подобие delay

я так понял можно создать подобную функцию sleep, с задержкой по времени, но почему-то при этом нарушается логика работы программы.

HTML5
1
2
3
<div id='run'>
 
</div>
CSS
1
2
3
4
5
6
7
#run {
  position: relative;
  width: 100px;
  height: 100px;
  background-color: blue;
  transition: 500ms;
}
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function sleep(milliseconds) {       
    const date = Date.now();        
    let currentDate = null;       
    do {               
       currentDate = Date.now();      
    } while (currentDate - date < milliseconds); 
} 
 
window.addEventListener("load", function(){
 
  let mgnTop = 0;
  let mgnLft = 0;
 
  mgnLft = 50;
  document.getElementById('run').style.marginLeft = mgnLft + 'px';
  
  sleep(500);
  mgnTop = 50;
  document.getElementById('run').style.marginTop = mgnTop + 'px';
 
});

по логике, для div блока применяется новый параметр смещающий стиль блока налево, далее пока идёт движение блока transition: 500ms, мы должны в теории замереть на это же время, и после чего дать команду на смещение (отступ сверху).

Но происходит странное, первый стиль не применяется, пока JS не выйдет из паузы, а когда он выходит, применяются сразу два стиля margin-top и margin-left из-за чего блок двигается не влево и вниз, а по диагонали.

Как замедлить программу JS чтобы не выполнять следующее смещение пока не закончится первое?

Можно конечно отслеживать document.getElementById('run').getProper tyValue('margin-top');
но зависать в while думаю плохая идея.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.02.2025, 12:24
Ответы с готовыми решениями:

Функция работает некорректно
Добрый день! Сделал функцию, которая должна удалить определённый символ в определённом тексте. Принцип работы: функция конкатенирует всё,...

Функция sleep
Доброго дня, подскажите пожалуйста. Имеется функция: function sleep(miliseconds) { var currentTime = new Date().getTime(); ...

работа с функцией, высчитывание разных суммы
вот бьюсь - никак не могу понять почему пишет значение не определено? &lt;html&gt; &lt;head&gt; &lt;script&gt; function...

28
 Аватар для voraa
1242 / 1142 / 178
Регистрация: 21.01.2024
Сообщений: 5,224
18.02.2025, 12:36
Вы не понимаете как работает цикл событий в js.
Когда происходит событие, начинает работать его обработчики.
Всякие перерасчеты стилей и рендер (отображение) экрана производятся после окончания работы обработчиков.
Т.е пока не завершится ваша функция (с циклом внутри) никаких изменений на экране не будет.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.addEventListener("load", function(){
 
  let mgnTop = 0;
  let mgnLft = 0;
 
  mgnLft = 50;
  document.getElementById('run').style.marginLeft = mgnLft + 'px';
  
  //sleep(500);
  setTimeout (() => {
      mgnTop = 50;
      document.getElementById('run').style.marginTop = mgnTop + 'px';
  }, 500);
 
});
2
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3813 / 1651 / 428
Регистрация: 14.03.2022
Сообщений: 4,122
18.02.2025, 15:03
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Можно конечно отслеживать document.getElementById('run').getProper tyValue('margin-top');
но зависать в while думаю плохая идея.
Отслеживание на клиенте выполняется не так.
https://learn.javascript.ru/mutation-observer
0
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531
18.02.2025, 15:16  [ТС]
Цитата Сообщение от voraa Посмотреть сообщение
Т.е пока не завершится ваша функция
я думал это обработчик для HTML документа т.е. все стили загружаются и после этого выполняется функция.

Хорошо, как выйти из положения? если запустить функцию вне обработчика есть великий шанс, что стили не успеют загрузится и логично код будет обращаться к тому чего нет.
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3813 / 1651 / 428
Регистрация: 14.03.2022
Сообщений: 4,122
18.02.2025, 15:43
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Хорошо, как выйти из положения?
Выше камрад voraa показал альтернативу.

Цитата Сообщение от voraa Посмотреть сообщение
JavaScript
1
2
3
4
5
//sleep(500);
setTimeout (() => {
      mgnTop = 50;
      document.getElementById('run').style.marginTop = mgnTop + 'px';
}, 500);
Добавлено через 3 минуты
Цитата Сообщение от SergeyKagen Посмотреть сообщение
я думал это обработчик для HTML документа т.е. все стили загружаются и после этого выполняется функция.
Так она у тебя и выполняется. Только не так, как хочешь ты.
JS однопоточный ЯП. И твоя программа не "спит", она именно выполняется в цикле
Цитата Сообщение от SergeyKagen Посмотреть сообщение
JavaScript
1
2
3
do {               
    currentDate = Date.now();      
} while (currentDate - date < milliseconds);
Ну и далее "по тексту"...
0
 Аватар для voraa
1242 / 1142 / 178
Регистрация: 21.01.2024
Сообщений: 5,224
18.02.2025, 15:56
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Хорошо, как выйти из положения?
А мой код, что не работает? Или работает не так, ка вы хотите?
0
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531
18.02.2025, 16:00  [ТС]
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function sleep(milliseconds) {       
    const date = Date.now();        
    let currentDate = null;       
    do {               
       currentDate = Date.now();      
    } while (currentDate - date < milliseconds); 
} 
 
window.addEventListener("load", function(){
 
  let mgnTop = 0;
  let mgnLft = 0;
 
  document.getElementById('run').style.marginLeft = mgnLft + 'px';
  document.getElementById('run').style.marginTop = mgnTop + 'px';
  
  let start = Date.now();
  let time_animation = 500;
  let timer = setInterval(function() {
    let timePassed = Date.now() - start;
        console.log(timePassed + ' / ' );
    if(timePassed < time_animation){ 
        document.getElementById('run').style.marginLeft = timePassed / 5 + 'px'; 
    }
    if(timePassed >= time_animation && timePassed < time_animation * 2){
        document.getElementById('run').style.marginTop = ((timePassed / 5) - (time_animation / 5)) + 'px';
    }
        if (timePassed > time_animation * 2) clearInterval(timer);
    }, 20);
 
});
но это такой геморой. 11 кадров прописывать, и привязывать изменения к времени высчитывать. Ох.... ладно надо думать.
0
 Аватар для voraa
1242 / 1142 / 178
Регистрация: 21.01.2024
Сообщений: 5,224
18.02.2025, 16:03
Цитата Сообщение от SergeyKagen Посмотреть сообщение
но это такой геморой.
Вы чего хотите то? По кускам кода не определить ваши потребности.
Словами их выразите.
0
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531
18.02.2025, 16:08  [ТС]
Боже, какой геморрой анимацию отрисовать)) Так и хочется, ты должен бороться со злом а не примкнуть к нему.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
window.addEventListener("load", function(){
 
  let mgnTop = 0;
  let mgnLft = 0;
 
  mgnLft = 50;
  document.getElementById('run').style.marginLeft = mgnLft + 'px';
  
  //sleep(500);
  setTimeout (() => {
      mgnTop = 50;
      document.getElementById('run').style.marginTop = mgnTop + 'px';
  }, 500);
  
  setTimeout (() => {
      mgnLft = 0;
      document.getElementById('run').style.marginLeft = mgnLft + 'px';
  }, 1000);
  
  setTimeout (() => {
      mgnTop = 0;
      document.getElementById('run').style.marginTop = mgnTop + 'px';
  }, 1500);
 
});
0
Эксперт .NET
 Аватар для Usaga
14114 / 9331 / 1350
Регистрация: 21.01.2016
Сообщений: 35,067
18.02.2025, 16:26
SergeyKagen, а здесь точно руками надо таймеры выставлять? Анимация силами CSS никак не подходит?
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3813 / 1651 / 428
Регистрация: 14.03.2022
Сообщений: 4,122
18.02.2025, 16:36
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Так и хочется, ты должен бороться со злом а не примкнуть к нему.
Ты просто пытаешься прикрыть свое неумение...
0
 Аватар для voraa
1242 / 1142 / 178
Регистрация: 21.01.2024
Сообщений: 5,224
18.02.2025, 16:58
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Так и хочется, ты должен бороться со злом а не примкнуть к нему.
Зло - незнание JS (и CSS)
Вариант 1
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const delay = (t) => new Promise (res => setTimeout(res, t))
 
window.addEventListener("load", async function(){
     
        let mgnTop = 0;
        let mgnLft = 0;
         
        mgnLft = 50;
        document.getElementById('run').style.marginLeft = mgnLft + 'px';
 
        await delay (500);
        mgnTop = 50;
        document.getElementById('run').style.marginTop = mgnTop + 'px';
 
        await delay (500);
        mgnLft = 0;
        document.getElementById('run').style.marginLeft = mgnLft + 'px';
 
        await delay (500);
        mgnTop = 0;
        document.getElementById('run').style.marginTop = mgnTop + 'px';  
    }
);
Вариант 2
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<head>
    <style>
#run {
    position: relative;
    width: 100px;
    height: 100px;
    background-color: blue;
}
#run.anim {
    animation: 2s linear 0s  move;
}
@keyframes move {
    0% {
        top: 0px;
        left: 0px;
    }  
    25% {
        left: 50px;
        top: 0px;
    }
    50% {
        left: 50px;
        top: 50px;
    }
    75% {
        left: 0px;
        top: 50px;
    }
    100% {
        top: 0px;
        left: 0px;
    }  
}
    </style>
</head>
<body>
    <div id='run'>
    </div>
<script>
window.addEventListener("load", function(){
    const drun = document.getElementById('run');
    drun.classList.add('anim')
    setTimeout (()=> drun.classList.remove('anim'), 2000)
})
</script>
</body>
0
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531
18.02.2025, 17:49  [ТС]
Да, я не знаю JS на профессиональном уровне. Но и ветка по-моему об этом говорит.

я не пойму, как передать в функцию параметры.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
for(var x = 2; x <= 11; x++){
 
    let delay = ((x-1)*500);        
 
    console.log(x + ' delay:' + delay);
    console.log('before [0]:' + marginTL[0] + ' [1]:' + marginTL[1] + ' [2]:' + marginTL[2]);
 
    setTimeout (() => {
        marginTL = frame_DC(marginTL, gen_command, x, W_Div, H_Div, id_str);
    }, delay);
    
    console.log('after [0]:' + marginTL[0] + ' [1]:' + marginTL[1] + ' [2]:' + marginTL[2]);
}
функция frame_DC принимает несколько параметров marginTL и gen_command массивы, остальное переменные.
сама функция вне setTimeout работает, внутри не видит. Я так понял, нужно эти параметры сначала передать в setTimeout? но как...?
0
 Аватар для voraa
1242 / 1142 / 178
Регистрация: 21.01.2024
Сообщений: 5,224
18.02.2025, 18:15
JavaScript
1
2
3
4
5
setTimeout (() => {
        marginTL = frame_DC(marginTL, gen_command, x, W_Div, H_Div, id_str);
}, delay);
    
console.log('after [0]:' + marginTL[0] + ' [1]:' + marginTL[1] + ' [2]:' + marginTL[2]);
Вот, что у вас получается.
Вы вызываете setTimeout. Она запускает таймер на время delay и говорит, что после срабатывания таймера надо вызвать функцию
JavaScript
1
2
3
() => {
        marginTL = frame_DC(marginTL, gen_command, x, W_Div, H_Div, id_str);
}
Сама он не ждет, когда сработает таймер и выполнится функция. А просто завершается. Завела будильник и пошла.
По завершению setTimeout выполнится
JavaScript
1
console.log('after [0]:' + marginTL[0] + ' [1]:' + marginTL[1] + ' [2]:' + marginTL[2]);
Это выполнится после завершения setTimeout, а не после функции, которая указана в нем.

Поэтому надо такие вещи писать используя async/await.
0
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531
18.02.2025, 18:23  [ТС]
я вывел setTimeout из тела for и заработало. Костыль, но там всего-то 11 команд
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3813 / 1651 / 428
Регистрация: 14.03.2022
Сообщений: 4,122
18.02.2025, 22:26
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Да, я не знаю JS на профессиональном уровне.
Нет никакого "профессионального уровня". Человек либо знает ЯП либо имеет слабое представление о нем.
Пока ты не поймешь как работает событийный цикл в JS, так и будешь блуждать во тьме.
https://learn.javascript.ru/event-loop
0
Эксперт .NET
 Аватар для Usaga
14114 / 9331 / 1350
Регистрация: 21.01.2016
Сообщений: 35,067
19.02.2025, 02:45
Очень интересный подход) Выше озвучили, что анимации на CSS делаются, как правило без таймеров. И пример даже привел ещё один. Но ТСу как будто бы пофигу)
0
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531
19.02.2025, 16:17  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Но ТСу как будто бы пофигу)
вы ошибаетесь, основную идею я понял и уловил, но мне это нужно сделать для одного раза, сделать проверить и выкинуть кусок кода в забвенье.

Однако с точки зрения образовательного контента я впитал информацию, и если честно она меня больше всех устраивает с анимацией CSS.

Но у меня как всегда много вопрос, я не особо хочу засорять форум этими вопросами.
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<head>
    <style>
#run {
    position: relative;
    width: 100px;
    height: 100px;
    background-color: blue;
}
#run.anim {
    animation: 2s linear 0s  move;
}
@keyframes move {
    0% {
        top: 0px;
        left: 0px;
    }  
    25% {
        left: 50px;
        top: 0px;
    }
    50% {
        left: 50px;
        top: 50px;
    }
    75% {
        left: 0px;
        top: 50px;
    }
    100% {
        top: 0px;
        left: 0px;
    }  
}
    </style>
</head>
<body>
    <div id='run'>
    </div>
<script>
window.addEventListener("load", function(){
    const drun = document.getElementById('run');
    drun.classList.add('anim')
    setTimeout (()=> drun.classList.remove('anim'), 2000)
})
</script>
</body>
например один из таких вопросов как с помощью JS изменить кадр, например в 0 кадре, написано
CSS
1
2
3
4
0% {
        top: 0px;
        left: 0px;
    }
а у меня версии анимаций разные, алгоритмы разные, и поэтому как поменять через JS вместо top: 0; на top: 20px;?

второе, если мне хочется изменить 2-й кадр, тот что 25%, как мне поменять процент времени с которого он начинается, например не 25% а 20%?

Ну и третье, что сильнее нагружает браузер JS или CSS? просто у меня есть анимация из шестерёнок и она тормозит на старых компьютерах. Тут или видео виновато на backgrounde или анимация.

Буду ещё искать как определить мощность компьютера, и скорость интернета. Надеюсь средствами JS на стороне клиента это как-то можно определить.

У JS много возможностей, я вкурсе. Просто всё и сразу я не смогу переварить, так устроен мой мозг.
0
 Аватар для voraa
1242 / 1142 / 178
Регистрация: 21.01.2024
Сообщений: 5,224
19.02.2025, 16:44
Цитата Сообщение от SergeyKagen Посмотреть сообщение
а у меня версии анимаций разные, алгоритмы разные, и поэтому как поменять через JS вместо top: 0; на top: 20px;?
Цитата Сообщение от SergeyKagen Посмотреть сообщение
У JS много возможностей,
Ну через CSSOM можно. Хотя посложнее, чем c DOM разбираться.
Если все определяется динамически, то только так. А если просто несколько вариантов, то проще несколько правил заготовить.
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Буду ещё искать как определить мощность компьютера, и скорость интернета. Надеюсь средствами JS на стороне клиента это как-то можно определить.
А мощность в чем определять? В л.с?
Вряд ли это можно.
Цитата Сообщение от SergeyKagen Посмотреть сообщение
Ну и третье, что сильнее нагружает браузер JS или CSS?
Считается, что CSS быстрее работает. Хотя тоже есть варианты. Например перемещение через translate считается более экономичным, чем перемещение изменением left и top, т.к там больше задействован графический процессор
0
7 / 8 / 3
Регистрация: 02.04.2018
Сообщений: 531
19.02.2025, 18:26  [ТС]
Цитата Сообщение от voraa Посмотреть сообщение
Ну через CSSOM можно. Хотя посложнее, чем c DOM разбираться.


у меня в CSS стилях прописан ID. Как его поменять через CSSOM? например с t-08-a-8 на t-08-a-5 ?

или вообще как вариант, это удалить эти строчки.

CSS
1
2
3
4
5
6
7
8
    /* QUESTION 8 */
    #div_5:has(#t-08-a-8:checked)>.slider  .results-q8 .check_0 {
        opacity: 0;
    }
 
    #div_5:has(#t-08-a-8:checked)>.slider  .results-q8 .check_O {
        opacity: 1;
    }
и как-то создать новые,

CSS
1
2
3
4
5
6
7
8
    /* QUESTION 8 */
    #div_5:has(#t-08-a-5:checked)>.slider  .results-q8 .check_0 {
        opacity: 0;
    }
 
    #div_5:has(#t-08-a-5:checked)>.slider  .results-q8 .check_O {
        opacity: 1;
    }
но как это сделать?

вроде нашёл что есть, getComputedStyle() - но она вроде как только читает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.02.2025, 18:26
Помогаю со студенческими работами здесь

Некорректная работа с id в IE6/7
Есть форма, в зависимости от выбора Способа доставки в этой форме, для пользователя должны отображаться различные поля контактных данных. В...

Работа с функциями setInterval() и clearInterval()
Если у кого есть выложите пример работы с этими функциями. Если быть точнее интерисует вызов этих функций по несколку раз для разных...

Некорректная работа скрипта
Проблема в if var quantity= $(&quot;#numberOrderWhisky&quot;).val(); var quantityInDB= $(&quot;#quantityWhiskeyInDB&quot;).val(); var price =...

Некорректная работа скрипта
Сей скрипт плавного перехода между страницами $(document).ready(function() { $(&quot;body&quot;).css(&quot;display&quot;,...

Некорректная работа Javascript при прокрутке превью в галерее
Имеем фотогалерею. Создаются превью с прокруткой. При наведении мышки - дрожание превьюшек и отсутствие прокрутки как таковой. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru