gpt4 book ai didi

javascript - 动画 html 元素的宽度

转载 作者:行者123 更新时间:2023-11-27 23:33:53 25 4
gpt4 key购买 nike

如何创建一个函数来增加(减少)给定 html 元素的宽度?下面是我这样做的尝试,但我认为这是非常糟糕的。如何改进我的代码?

function foo(elem, num) {
var i = 0;

if (!elem.style.width) {
setTimeout(function bar() {
if (i < num) {
elem.style.width = i++ + '%';
elem.innerHTML = i++;
}

setTimeout(bar, 30);
}, 30);
} else {
i = num;
setTimeout(function baz() {
if (i > 0) {
elem.style.width = i-- + '%';
elem.innerHTML = i--;
}

setTimeout(baz, 30);
}, 30);
}
}
div {
height: 25px;
width: 25px;
background: red;
cursor: pointer;
}
<div onclick="foo(this, 75)">0%</div>

最佳答案

还有一些需要改进的地方:

  • 首先,您当前正在跳过每一秒的百分比,因为您在函数中执行了 i++/i-- 两次,一个接一个(因此您正在设置将宽度设置为 0% 并显示 1%,然后将其设置为 2% 并显示 3% 等)
  • 其次,您可以使用requestAnimationFrame(对于较旧的浏览器,包括polyfill)来获得更好的性能
  • 第三,您可以通过计算方向(1-1 取决于您是否想要i 增加或减少)并且只有一个 bar/baz 函数

这是我的看法:

function foo(elem, num) {
var initialWidth = elem.style.width;
var i = initialWidth ? num : 0;
var direction = initialWidth ? -1 : 1;

function bar() {
elem.style.width = i + '%';
elem.innerHTML = '' + i;
i += direction;

if (i <= num && i >= 0)
window.requestAnimationFrame(bar);
}
window.requestAnimationFrame(bar);

return function reset() {
elem.style.width = initialWidth;
elem.innerHTML = '';
}
}


var animated = false,
reset1, reset2;
document.getElementsByClassName('grower-parent')[0].onclick = function() {
if (!animated) {
animated = true;
reset1 = foo(document.getElementsByClassName('grower-1')[0], 50);
reset2 = foo(document.getElementsByClassName('grower-2')[0], 50);
return;
}
animated = false;
reset1();
reset2();
};
.grower-1,
.grower-2 {
display: block;
background-color: blue;
height: 1em;
color: white;
width: 0;
}
<div class="grower-parent">
<div class="grower-1" style="width:50%"></div>
<div class="grower-2"></div>
</div>

编辑:现在,第一次单击将启动动画,第二次单击将重置动画。

编辑 2: 一个更复杂的程序,实际上可以在动画实现目标或返回初始值之间切换(以及在 px 之间切换% 单位)。您现在可以开始了解为什么我们有专用动画库,我们可以将其插入到我们的项目中,而不必重新发明轮子:)(尝试 GSAP ,太棒了)

function animateTo(element, to) {
if (to === undefined) return function() {};

var animating = true;
var width, match;
var unit = (to === Number(to)) ? (width = to, 'px') : (match = to.match(/(\d+)\s*(px|%)/), width = Number(match[1]), match[2]);
var initialWidth = unit === 'px' ? element.offsetWidth : (match = element.style.width.match(/(\d+)\s*%/)) ? Number(match[1]) : Math.round(element.offsetWidth / ((element.offsetParent || element).offsetWidth) * 100);
var currentWidth = initialWidth;
var direction = initialWidth <= width ? 1 : -1;

function animate() {
element.style.width = currentWidth + unit;
element.innerHTML = currentWidth + unit;
currentWidth += direction;

if (direction * currentWidth <= direction * width) {
if (animating) window.requestAnimationFrame(animate);
} else {
animating = false;
}
}

function stopAnimation() {
animating = false;
}

window.requestAnimationFrame(animate);
return stopAnimation;
}

function toggleWidth(element, to) {
var initial = element.style.width ? element.style.width : element.offsetWidth + 'px';
var toAnimation = true;
var stopAnimation;
return function toggle() {
if (stopAnimation) stopAnimation();
if (toAnimation) {
stopAnimation = animateTo(element, to);
} else {
stopAnimation = animateTo(element, initial);
}
toAnimation = !toAnimation;
}
}

var toggle = toggleWidth(document.getElementsByClassName('grower-1')[0], '10%');
var toggle2 = toggleWidth(document.getElementsByClassName('grower-2')[0], '200px');
document.getElementsByClassName('grower-parent')[0].onclick = function() {
toggle();
toggle2();
};
.grower-1,
.grower-2 {
display: block;
background-color: blue;
height: 1em;
color: white;
width: 0;
}
<div class="grower-parent">
<div class="grower-1" style="width:400px"></div>
<div class="grower-2" style="width:5%"></div>
</div>

关于javascript - 动画 html 元素的宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34295637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com