【问题标题】:Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function未捕获的类型错误:无法在“窗口”上执行“requestAnimationFrame”:作为参数 1 提供的回调不是函数
【发布时间】:2020-12-22 18:45:03
【问题描述】:

我不太确定我在这里使用 requestAnimationFrame 出了什么问题,因为它似乎可以正常工作,但它抛出了这个错误。

未捕获的 TypeError:无法在“窗口”上执行“requestAnimationFrame”:作为参数 1 提供的回调不是函数。

我正在尝试每 3000 毫秒将一个元素旋转 90 度,然后淡入/淡出其他一些元素。这可能不是最优雅的方式,我怀疑不是,我对 JS 的理解相当基础。因此,如果有人能解释导致此错误的原因,我将不胜感激。

var iteration = 0,
    degrees = 0;   

function rotate_by_90(degrees, iteration) {
    if(iteration <= 3) {
        var deg = degrees - 90,
            new_deg = deg;

        setTimeout(function() {
            $('#rotate').css('transform', 'translateZ(-60px) rotateX(' + deg + 'deg');
            console.log(new_deg + ' degrees');
            iteration++;
            console.log(iteration + ' iteration');
            requestAnimationFrame(rotate_by_90(new_deg, iteration));            
        }, 3000);
    } else {
        $('#rotating_text').fadeOut();
        $('#animation_overlay').fadeIn();
    }
};

requestAnimationFrame(rotate_by_90(degrees,iteration));

HTML

<div id="rotating_text" class="rotating_text">
    <span>Some text </span>
    <div class="rotate_container">
        <div id="rotate" class="rotate">
            <span>thing 1</span>
            <span>thing 2</span>
            <span>thing 3</span>
            <span>thing 4</span>
        </div>                              
    </div>
</div>  

<div id="animation_overlay" class="animation_overlay">                      
    <span>Some stuff</span>
</div>

另外,如果有人可以提出更好的方法(包括在整个事情完成后循环重新开始,那将不胜感激!)

【问题讨论】:

    标签: javascript jquery typeerror requestanimationframe


    【解决方案1】:

    不,它不起作用 - 你自己调用一次rotate_by_90(立即,不是在动画帧准备好时!)并将其返回值(undefined)传递给requestAnimationFrame。相反,你必须传递一个function 转换成requestAnimationFrame,浏览器会调用它。

    你也可以传递一个匿名函数,所以你的代码可以通过像这样添加() =&gt;来修复:

    requestAnimationFrame(() => rotate_by_90(degrees,iteration));
    

    关于如何以更好的方式总体上做到这一点,我可以建议使用异步函数和实际循环:

    // First, get some promisified versions of setTimeout and requestAnimationFrame:
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
    const waitForAnimationFrame = () => new Promise(resolve => requestAnimationFrame(resolve))
    
    // Next, our main function:
    async function rotationAnimation () {
      let degrees = 0
    
      // Loop from 0 to 3
      for (let iteration = 0; iteration <= 3; iteration++) {
        // Update degrees
        degrees -= 90
        
        // Wait 3 seconds + animation frame
        await delay(3000)
        await waitForAnimationFrame()
        
        // Log variables
        console.log(`Iteration ${iteration}, ${degrees} degrees`)
        
        // Update the CSS
        $('#rotate').css('transform', `translateZ(-60px) rotate(${degrees}deg)`)
      }
    
      // After the loop is done, crossfade the elements
      $('#rotating_text').fadeOut()
      $('#animation_overlay').fadeIn()
    }
    
    // Call our main function, and handle rejections:
    rotationAnimation().catch(e => console.error('Error during animation:', e))
    .rotate {
      width: 60px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="rotating_text" class="rotating_text">
        <span>Some text </span>
        <div class="rotate_container">
            <div id="rotate" class="rotate">
                <span>thing 1</span>
                <span>thing 2</span>
                <span>thing 3</span>
                <span>thing 4</span>
            </div>                              
        </div>
    </div>  
    
    <div id="animation_overlay" class="animation_overlay">                      
        <span>Some stuff</span>
    </div>

    注意:我保留了单独计算迭代次数的原始逻辑,从 0° 开始,然后在第一次更新元素之前立即减少到 -90°。但是,我将rotateX 更改为rotate,否则-90°/-270° 状态在示例中是不可见的,因为您正在查看文本的零宽度“边缘”。

    (顺便说一句,你也可以只使用 CSS 动画来完成这一切,而不需要任何 JavaScript。)

    【讨论】:

    • requestAnimationFrame(rotate_by_90.bind(this, degrees, iteration)) 也可以。
    • 是的,但阅读和理解起来不太直观。
    • 非常感谢,这真的很有帮助,我现在不得不进一步调整以添加更多动画,但会以您的建议为起点,再次感谢!
    猜你喜欢
    • 2014-03-29
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 2019-11-20
    相关资源
    最近更新 更多