Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/90.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript没有设置动画_Javascript_Html_Css_Easing - Fatal编程技术网

Javascript没有设置动画

Javascript没有设置动画,javascript,html,css,easing,Javascript,Html,Css,Easing,试图在javascript中实现简单的简化(没有jQuery),但不幸的是,当点击按钮时,似乎没有任何动画(见下文) 我的目标是通过改变第一个项目的边距左侧属性,使隐藏列表项目(最后一个项目)可见。我知道这不是CSS问题,因为手动修改样式会移动列表,但我不确定问题是什么。我的猜测是如何调用ease函数,但更改参数对我来说仍然不起作用 放松部分如下,完整代码如下: JS: var start=document.getElementById('start'), list=document.getEl

试图在javascript中实现简单的简化(没有jQuery),但不幸的是,当点击按钮时,似乎没有任何动画(见下文)

我的目标是通过改变第一个项目的边距左侧属性,使隐藏列表项目(最后一个项目)可见。我知道这不是CSS问题,因为手动修改样式会移动列表,但我不确定问题是什么。我的猜测是如何调用ease函数,但更改参数对我来说仍然不起作用

放松部分如下,完整代码如下:

JS:

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
as
parseFloat(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毫秒),因此它们同时执行,导致元素“跳转”。