Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.06.2022, 18:00
Интересующийся
Отправить личное сообщение для borzik2h Посмотреть профиль Найти все сообщения от borzik2h
 
Регистрация: 12.03.2022
Сообщений: 15

Отменить повторное нажатие
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title></title>
	<style>
		html, body {
			height: 100%;
		}

		body {
			font-family: Arial;
			margin: 0;
			padding: 0;
		}

		.wrapper {
			width: 50%;
			margin: 1% auto;
		}

		.outer {
			position: relative;
		}

		.slideUI {
			width: 0;
			text-align: center;
			border: 3px solid #ccc;
			display: none;
			overflow: hidden;
			position: absolute;
		}

		.button {
			margin-top: 10px;
		}

		.clone {
			position: relative;
			left: -99999;
			z-index: -99999;
			display: block;
			height: auto;
			width: auto;
			border: 3px solid #ccc;
		}
	</style>
</head>
<body>
	<div class="wrapper">
		<button class="button" onclick="slideUI(this.nextElementSibling.firstElementChild, 1000)">Toggle</button>
		<div class="outer">
			<div class="slideUI">
				<h1>Lorem ipsum</h1>
				<p>Lorem ipsum, dolor sit amet consectetur adipisicing, elit. Vitae eveniet nesciunt suscipit consequuntur id rem, earum totam eos eligendi labore sit illo fuga cumque neque ipsa fugiat quae sunt omnis?</p>
			</div>
		</div>
	</div>

	<script>
		let counter = 0;
		let isAnimated = false;

		function animate({timing, draw, duration}) {
			let start = performance.now();

			requestAnimationFrame(function doAnimation(time) {
				let timeFraction = (time - start) / duration;
				if (timeFraction > 1) timeFraction = 1;

				let progress = timing(timeFraction);

				draw(progress);

				if (timeFraction < 1) {
					requestAnimationFrame(doAnimation);
				}
			});
		}

		function getCloneSizes(elem) {
			const sizes = {};
			const borderWidth = (parseInt(getComputedStyle(elem).borderWidth) * 2);
			const clone = elem.cloneNode(true);
			clone.classList.add('clone');
			elem.parentNode.append(clone);
			sizes.width = clone.offsetWidth - borderWidth;
			sizes.height = clone.offsetHeight - borderWidth;
			clone.remove();

			return sizes;
		}

		function slideUI(elem, duration) {
			if (isAnimated) return false;

			isAnimated = true;

			const sizes = getCloneSizes(elem);

			elem.style.display = 'block';
			elem.style.height = sizes.height + 'px';
			elem.style.width = sizes.width + 'px'
			elem.style.left = `-${sizes.width}px`;
			elem.style.clip = `rect(auto, 0px, auto, 0px)`;

			let start = parseInt(elem.style.left);

			animate({
				duration: duration,
				timing(timeFraction) {
					return timeFraction;
				},
				draw(progress) {
					let elemWidth = sizes.width + (parseInt(getComputedStyle(elem).borderWidth) * 2);
					let t = progress * elemWidth;

					if (counter % 2 != 0) {
						elem.style.clip = `rect(auto, ${t}px, auto, ${elemWidth - t}px)`;
						elem.style.left = start + t + 'px';
					} else {
						elem.style.clip = `rect(auto, ${elemWidth}px, auto, ${t}px)`;
						elem.style.left = 0 - t + 'px';
					}
				}
			});

			counter++;

			isAnimated = false;
		}
	</script>
</body>
</html>


Почему не отменяется повторное нажатие во время анимации? Здесь нет ассинхронщины!?

if (isAnimated) return false;

Последний раз редактировалось borzik2h, 05.06.2022 в 18:03.
Ответить с цитированием
  #2 (permalink)  
Старый 05.06.2022, 18:35
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

borzik2h,
у вас нет запрета на время анимации, добавьте и будет вам счастье.
Ответить с цитированием
  #3 (permalink)  
Старый 05.06.2022, 20:56
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

анимация на js
borzik2h,
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
    <style>
        html,
        body {
            height: 100%;
        }

        body {
            font-family: Arial;
            margin: 0;
            padding: 0;
        }

        .wrapper {
            width: 50%;
            margin: 1% auto;
        }

        .outer {
            overflow: hidden;
        }

        .slideUI {
            text-align: center;
            border: 3px solid #ccc;
            transform: translateX(-100%);
        }

        .button {
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <div class="wrapper">
        <button class="button" onclick="slideUI(this.nextElementSibling.firstElementChild, 1000)">Toggle</button>
        <div class="outer">
            <div class="slideUI">
                <h1>Lorem ipsum</h1>
                <p>Lorem ipsum, dolor sit amet consectetur adipisicing, elit. Vitae eveniet nesciunt suscipit consequuntur id rem, earum totam eos eligendi labore sit illo fuga cumque neque ipsa fugiat quae sunt omnis?</p>
            </div>
        </div>
    </div>
    <script>
        let counter = 0;
        let isAnimated = false;

        function animate({
            timing,
            draw,
            duration
        }) {
            let start = performance.now();
            requestAnimationFrame(function doAnimation(time) {
                let timeFraction = (time - start) / duration;
                if (timeFraction > 1) timeFraction = 1;
                let progress = timing(timeFraction);
                draw(progress);
                if (timeFraction < 1) {
                    requestAnimationFrame(doAnimation);
                } else isAnimated = false;
            });
        }

        function slideUI(elem, duration) {
            if (isAnimated) return false;
            isAnimated = true;
            animate({
                duration: duration,
                timing(timeFraction) {
                    return timeFraction;
                },
                draw(progress) {
                    let t = counter % 2 ? (progress - 1) * 100 : -progress * 100;
                    elem.style.transform = `translateX(${t}%)`;
                }
            });
            counter++;
        }
    </script>
</body>

</html>
Ответить с цитированием
  #4 (permalink)  
Старый 06.06.2022, 08:30
Интересующийся
Отправить личное сообщение для borzik2h Посмотреть профиль Найти все сообщения от borzik2h
 
Регистрация: 12.03.2022
Сообщений: 15

рони,
спасибо, ваш вариант гораздо лучше.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как предотвратить повторное нажатие на radio button? Katy93 Общие вопросы Javascript 2 03.06.2022 18:36
Повторное нажатие кнопки поле таймута solic2010 Events/DOM/Window 7 27.09.2019 13:07
проверка на повторное нажатие Freekazoid jQuery 7 02.12.2016 08:24
События - focusout и click отменить повторное срабатывание функции egorychmaster Элементы интерфейса 1 25.06.2015 13:35
Повторное нажатие vladimircape jQuery 6 17.12.2012 18:03