Javascript没有设置动画
试图在javascript中实现简单的简化(没有jQuery),但不幸的是,当点击按钮时,似乎没有任何动画(见下文) 我的目标是通过改变第一个项目的边距左侧属性,使隐藏列表项目(最后一个项目)可见。我知道这不是CSS问题,因为手动修改样式会移动列表,但我不确定问题是什么。我的猜测是如何调用ease函数,但更改参数对我来说仍然不起作用 放松部分如下,完整代码如下: JS:Javascript没有设置动画,javascript,html,css,easing,Javascript,Html,Css,Easing,试图在javascript中实现简单的简化(没有jQuery),但不幸的是,当点击按钮时,似乎没有任何动画(见下文) 我的目标是通过改变第一个项目的边距左侧属性,使隐藏列表项目(最后一个项目)可见。我知道这不是CSS问题,因为手动修改样式会移动列表,但我不确定问题是什么。我的猜测是如何调用ease函数,但更改参数对我来说仍然不起作用 放松部分如下,完整代码如下: JS: var start=document.getElementById('start'), list=document.getEl
var start=document.getElementById('start'),
list=document.getElementById('my-list'),
imgs=list.getElementsByTagName('img'),
last_img=imgs[imgs.length-1];
缓解=功能(t、b、c、d){
如果((t/=d/2)<1)返回c/2*t*t+b;
返回-c/2*((-t)*(t-2)-1)+b;
},
移位\u imgs=功能(el){
var orig_value=parseFloat(el.style.marginLeft),
end_值=-37,
change=Math.abs(结束值-初始值),
持续时间=1,//1秒
时间=0;
对于(变量i=0;i
您的原始值是NaN
asparseFloat(el.style.marginLeft)
不返回任何内容,即使您在css中设置了初始值。i、 e:左边距:15px代码>仍将不返回任何内容
您可以使用,类似于此:
window.getComputedStyle(el, null).getPropertyValue("margin-left");
getElementMarginLeftAsFloat = function (el) {
var pxValue = window.getComputedStyle(el, null).getPropertyValue("margin-left");
var valueOnly = pxValue.substring(0, pxValue.length - 2);
return parseFloat(valueOnly);
}
shift_imgs = function (el) {
var orig_value = getElementMarginLeftAsFloat(el),
end_value = -37,
change = Math.abs(end_value - orig_value),
duration = 1, // 1 second
time = 0;
function doShift() {
currentValue = getElementMarginLeftAsFloat(el);
if(currentValue+1 > change){
return;
};
el.style.marginLeft = (currentValue + 1) + 'px';
time = ease(time, orig_value, change, duration);
setTimeout(doShift, time);
}
doShift();
};
这将为您提供实际的当前值以及px
,即:0px
(即使在CSS中设置为em
或pt
,它也始终返回px
中的值)
因此,您需要删除px
并获取浮点值
您可以将其包装为类似以下内容的小辅助对象:
window.getComputedStyle(el, null).getPropertyValue("margin-left");
getElementMarginLeftAsFloat = function (el) {
var pxValue = window.getComputedStyle(el, null).getPropertyValue("margin-left");
var valueOnly = pxValue.substring(0, pxValue.length - 2);
return parseFloat(valueOnly);
}
shift_imgs = function (el) {
var orig_value = getElementMarginLeftAsFloat(el),
end_value = -37,
change = Math.abs(end_value - orig_value),
duration = 1, // 1 second
time = 0;
function doShift() {
currentValue = getElementMarginLeftAsFloat(el);
if(currentValue+1 > change){
return;
};
el.style.marginLeft = (currentValue + 1) + 'px';
time = ease(time, orig_value, change, duration);
setTimeout(doShift, time);
}
doShift();
};
另一个问题是实际元素的移动发生在循环内部执行的setTimeout
中。调用setTimeout
的循环使每个setTimeout
几乎同时排队,因此它们几乎同时执行,导致元素只是跳转
您可以在方法中使用递归子方法,该方法使用setTimeout
调用自身,直到完成为止。这样,每个setTimeout
仅在指定的间隔后触发,导致它们以足够接近指定间隔的间隔执行,类似如下:
window.getComputedStyle(el, null).getPropertyValue("margin-left");
getElementMarginLeftAsFloat = function (el) {
var pxValue = window.getComputedStyle(el, null).getPropertyValue("margin-left");
var valueOnly = pxValue.substring(0, pxValue.length - 2);
return parseFloat(valueOnly);
}
shift_imgs = function (el) {
var orig_value = getElementMarginLeftAsFloat(el),
end_value = -37,
change = Math.abs(end_value - orig_value),
duration = 1, // 1 second
time = 0;
function doShift() {
currentValue = getElementMarginLeftAsFloat(el);
if(currentValue+1 > change){
return;
};
el.style.marginLeft = (currentValue + 1) + 'px';
time = ease(time, orig_value, change, duration);
setTimeout(doShift, time);
}
doShift();
};
通过调用setTimeout
函数本身,它释放了资源,确保元素的绘制可以在每次“迭代”之间进行
我更新了您的代码以使用这种方法,现在它似乎可以工作了
-使用计算样式设置运动动画
您很可能可以通过许多其他方式完成这项工作,也可以肯定地美化此代码,但这两种方式都可以让您开始使用。为什么不使用CSS转换?你的指尖上有一块石头;)@NiettheDarkAbsol是的,我很清楚CSS3,但这更多的是一个人练习:)足够公平!我自己也做过这个练习,所以我完全理解:)但主要问题是左边距:123
无效。有效的CSS是左边距:123px
-记住添加单位,即使是在JavaScript中;)很好地抓住了弗朗索瓦的打字错误!我更新了代码和小提琴,但不幸的是,我仍然没有看到动画。是不是在1秒内移动37像素对动画来说太快了以至于无法被注意到?@smaili:啊,是的,我现在看到它只是跳跃。我不明白你的期望,并假设你点击每像素。很抱歉。我现在更新了答案,以确保动画实际发生。for循环不起作用。元素的绘制仅仅发生在循环完成之后。我用一个递归子方法替换了循环,该方法在setTimeout
内不断调用自己,从而导致绘图执行每个“迭代”。是的,这就解决了它。感谢弗朗索瓦的帮助和详细的回答@斯迈利:我现在也更新了我关于为什么循环“似乎”不起作用的解释。循环中的setTimeout
通常是有效的,尽管在您的示例中,循环执行得如此之快,以至于几乎在同一时间将所有setTimeout
调用排队,其间只有一毫秒(可能是2毫秒),因此它们同时执行,导致元素“跳转”。