未捕获的类型错误:无法在“窗口”上执行“requestAnimationFrame”:作为参数 1 提供的回调不是函数
Posted
技术标签:
【中文标题】未捕获的类型错误:无法在“窗口”上执行“requestAnimationFrame”:作为参数 1 提供的回调不是函数【英文标题】:Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function 【发布时间】: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));
<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>
另外,如果有人可以提出更好的方法(包括在整个事情完成后循环重新开始,那将不胜感激!)
【问题讨论】:
【参考方案1】:不,它不起作用 - 你自己调用一次rotate_by_90
(立即,不是在动画帧准备好时!)并将其返回值(undefined
)传递给requestAnimationFrame
。相反,你必须传递一个function 转换成requestAnimationFrame
,浏览器会调用它。
你也可以传递一个匿名函数,所以你的代码可以通过像这样添加() =>
来修复:
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($degreesdeg)`)
// 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))
也可以。
是的,但阅读和理解起来不太直观。
非常感谢,这真的很有帮助,我现在不得不进一步调整以添加更多动画,但会以您的建议为起点,再次感谢!以上是关于未捕获的类型错误:无法在“窗口”上执行“requestAnimationFrame”:作为参数 1 提供的回调不是函数的主要内容,如果未能解决你的问题,请参考以下文章
未捕获的类型错误:无法读取未定义的属性“toLowerCase”
未捕获的类型错误:无法读取未定义的属性“createDocumentFragment”
错误未捕获类型错误:无法读取完整日历上未定义的属性“hasTime”
未捕获的类型错误:无法读取文本字段上未定义错误的属性“toLowerCase”