Javascript 函数完成所需时间比预期时间长

Javascript 函数完成所需时间比预期时间长,javascript,Javascript,我创建了一个简单的滑动函数,它可以使元素在给定的时间内出现或消失 我构建此函数的公式是:ms=1像素/(初始大小/持续时间),基本上计算从元素的高度或宽度减去prevSize&&size>prevSize)el.style[dim]=--size+“px”; /*如果el不可见*/ 否则,如果(prevSize>initSize&&size,您需要调整步长,即每次迭代要添加/删除的像素数,并调整延迟时间。下面是一个改进版本,大约需要1.1秒 function slide(el, duration

我创建了一个简单的滑动函数,它可以使元素在给定的时间内出现或消失

我构建此函数的公式是:
ms=1像素/(初始大小/持续时间)
,基本上计算从元素的
高度
宽度
减去
<1px
之前应该经过多少毫秒

我的数学逻辑是,函数应该在1000毫秒内完成,但对我来说,完成所需的时间看起来要多得多,而不知道需要多少时间

为什么要花费超过1s的时间才能完成,原因是什么

代码:

/*----JavaScript---*/
功能幻灯片(el、持续时间、方向){
/*违约*/
持续时间=持续时间| | 1000,方向=方向| |“垂直”;
变量
尺寸=(方向==“水平”)?“宽度”:“高度”,
/*获取el在“px”中的高度或宽度*/
size=initSize=parseFloat(
getComputedStyle(el,null).getPropertyValue(dim)| | el.style[dim]
),
/*获取以前的大小,以便将el恢复到它*/
prevSize=el.样式[“prev”+dim]| | 0,
/*计算减去1px前应通过的毫秒数*/
ms=1/(初始大小/持续时间),
间隔=设置间隔(函数(){
/*如果el是可见的*/
如果(initSize>prevSize&&size>prevSize)el.style[dim]=--size+“px”;
/*如果el不可见*/

否则,如果(prevSize>initSize&&size,您需要调整步长,即每次迭代要添加/删除的像素数,并调整延迟时间。下面是一个改进版本,大约需要1.1秒

function slide(el, duration, direction) {
  /* Default */
  duration = duration || 1000, direction = direction || "vertical";

  var dim = (direction === "horizontal") ? "width" : "height",

    /* Get how tall or wide el is in 'px' */
    size = initSize = parseFloat(
      getComputedStyle(el, null).getPropertyValue(dim) || el.style[dim]
    ),

    /* Get the previous size, so as to restore el to it */
    prevSize = el.style["prev" + dim] || 0;

    /* Calculating how many ms should pass before subtracting 1px*/
    var step = 1;
     var ms = 1 / (initSize / duration)
    if(ms<10){
        ms=10;
        step = 10*(initSize/duration);
        console.log(ms,step)
    }
      var now=new Date();
      var interval;var i=0;
    var animate = function() {
    i++;
        interval=setTimeout(animate,ms);
      /* If el is visible */
      if (initSize > prevSize && size > prevSize) el.style[dim] = (size=size-step) + "px";

      /* If el is not visible */
      else if (prevSize > initSize && size <= prevSize) el.style[dim] = (size=size+step) + "px";

      /* Clear the interval when 0 is reached and cache the previous size */
      else {
        console.log("oops", new Date()-now,size,step,i)
        el.style["prev" + dim] = initSize;
        clearInterval(interval);
      }
    };
    //var interval = setInterval(animate, ms);
    animate();
}
slide(document.getElementById("a"));
功能幻灯片(el、持续时间、方向){
/*违约*/
持续时间=持续时间| | 1000,方向=方向| |“垂直”;
变量dim=(方向==“水平”)?“宽度”:“高度”,
/*获取el在“px”中的高度或宽度*/
size=initSize=parseFloat(
getComputedStyle(el,null).getPropertyValue(dim)| | el.style[dim]
),
/*获取以前的大小,以便将el恢复到它*/
prevSize=el.样式[“prev”+dim]| | 0;
/*计算减去1px前应通过的毫秒数*/
var阶跃=1;
var ms=1/(初始大小/持续时间)
如果(ms prevSize&&size>prevSize)el.style[dim]=(尺寸=尺寸步长)+“px”;
/*如果el不可见*/

否则,如果(prevSize>initSize&&size)在读了Jaromanda X的评论后产生了一些想法,我最终使用了
window.requestAnimationFrame()
,因为它比
setInterval()
更有效,而且也不会强制浏览器重新绘制

这反过来又使我将公式从面向时间的(
ms=1/(初始大小/持续时间)
)更改为面向像素的(
px=frame*(初始大小/持续时间)

现在滑动更加平滑,非常接近
1000ms
,只有
5-7ms
的差异,我相信会发生,因为我将
变量设置为
1000/60
,没有考虑可能发生的帧速率下降

代码:

/*----JavaScript---*/
功能幻灯片(el、持续时间、方向){
/*设置默认值并记录开始日期*/
var a=Date.now();
持续时间=持续时间| | 1000,方向=方向| |“垂直”;
变量
尺寸=(方向==“水平”)?“宽度”:“高度”,
/*获取el在“px”中的高度或宽度*/
size=initSize=parseFloat(
getComputedStyle(el,null).getPropertyValue(dim)| | el.style[dim]
),
/*获取以前的大小,以便将el恢复到它*/
prevSize=el.样式[“prev”+dim]| | 0,
/*计算每帧应加/减多少像素*/
帧=1000/60,
px=帧*(初始大小/持续时间),
步骤=(initSize>prevSize)?-px:px;
requestAnimationFrame(函数转换(){
el.style[dim]=(尺寸>0)?(尺寸+=步长)+“px”:(尺寸=0);
如果(大小==0){
el.style[“prev”+dim]=初始尺寸;
//element.style.prevDisplay=initDisplay;
console.log(Date.now()-a)
}else window.requestAnimationFrame(变换);
},框架);
}
幻灯片(document.getElementById(“a”),1000);


ms
的值是多少?它越小,计时就越不准确-我将查看
请求动画帧
并重构代码以减去每个动画帧的特定数量的像素-换句话说,计算要减去的像素数量,这取决于自前一帧-以更平滑一致的动画结束您的函数从未完成:它从未到达
clearInterval()
。检查浏览器的控制台…另外,关于您的评论,“完成所需的时间看起来明显更多,但不确定需要多少时间”,为什么不在开始之前,在调用
clearInterval()
时,使用
console.log(Date.now())
测量它,或者如果我们有一个高度为
300px
的元素,并且我们设置的持续时间为
300ms
ms
将等于
1
(1/(300px/300ms))@nnnnnn对此表示抱歉,这只是我的代码片段中的一个输入错误。谢谢提示。延迟小于10毫秒的setInterval和setTimeout通常不那么准确,并且会随浏览器而变化。在您的情况下,它大约是3.33毫秒,这就是为什么需要很长时间,大约1.3秒。嗨,谢谢您的回答。它确实将滑动时间减少到1100毫秒,这是值得打赌的比我的要多,所以我投了一票