代码如何检测是否在动画帧内运行?

问题描述 投票:0回答:4

如果某个函数被传递到

requestAnimationFrame()
,该函数如何检测到它正在动画帧内被调用?

f.e.

function someFunction() {
  if (/* What goes here? */) {
    console.log('Inside animation frame.')
  }
  else {
    console.log('Not inside animation frame.')
  }
}

// The following lines should not be modified for the answer.
someFunction() // logs "Not inside animation frame."
requestAnimationFrame(someFunction) // eventually logs "Inside animation frame."

最后两行不应修改。我很想知道是否可以检测到这种情况,而不需要用户记住以两种不同的方式使用该功能。最终用户应该像平常一样使用该函数,而不知道我的函数检测到用例。

javascript requestanimationframe
4个回答
4
投票

目前无法获取 Javascript 中调用代码的上下文,因此除非您进行更改,否则您无法执行您想要的操作

requestAnimationFrame()
,但值得庆幸的是您可以做到这一点。试试这个...

// save a reference to the existing method and then override it...
window._requestAnimationFrame = window.requestAnimationFrame;
window.requestAnimationFrame = function(callback) {
	return window._requestAnimationFrame(function() {
		callback(true);
	});
}

function someFunction() {
	if (arguments.length && arguments[0]) {
		console.log('Inside animation frame.')
	}
	else {
		console.log('Not inside animation frame.')
	}
}

someFunction();
requestAnimationFrame(someFunction);


2
投票

将我自己的答案放在这里以供参考(感谢@phuzi,@Archer和@spender):

// save a reference to the existing method and then override it...
window.requestAnimationFrame = function (raf) { return function(callback) {
  return raf(function(time) {
    callback(time, true);
  });
}}(window.requestAnimationFrame.bind(window))

function someFunction(time, inFrame = false) {
  if (inFrame) {
    console.log('Inside animation frame.')
  }
  else {
    console.log('Not inside animation frame.')
  }
}

someFunction(); // logs "Not inside animation frame."
someFunction(63245); // still logs "Not inside animation frame."
requestAnimationFrame(someFunction); // eventually logs "Inside animation frame."


0
投票

您可以

bind
您传递给
requestAnimationFrame
的函数。

function someFunction(isInsideAnimationFrame, domHighResTimestamp) {
  if (isInsideAnimationFrame) {
    console.log('Inside animation frame.')
  }
  else {
    console.log('Not inside animation frame.')
  }
}

someFunction() // logs "Not inside animation frame."

requestAnimationFrame(someFunction.bind(null, true)) // eventually logs "Inside animation frame."

有关其工作原理的详细信息,请参阅 Function.prototype.bind

更新

查看 window.requestAnimationFrame 的文档,回调即

someFunction
将使用
DOMHighResTimeStamp
进行调用,即 .

someFunction
可以用

检测到这一点
function someFunction(domHighResTimestamp) {
  if (domHighResTimestamp) {
    console.log('Inside animation frame.')
  }
  else {
    console.log('Not inside animation frame.')
  }
}

不幸的是,不能保证使用

someFunction
的人不会将其称为传递值。


0
投票

你可以这样做:

它导出

getIsDuringAnimationFrame
并修补原生
requestAnimationFrame
功能。

let animationFrameCallbacksCount = 0;

const originalRequestAnimationFrame = window.requestAnimationFrame.bind(window);

window.requestAnimationFrame = function requestAnimationFrame(callback: (time: number) => void) {
  return originalRequestAnimationFrame((time) => {
    try {
      animationFrameCallbacksCount++;
      callback(time);
    } finally {
      animationFrameCallbacksCount--;
    }
  })
}

export function getIsDuringAnimationFrame() {
  return animationFrameCallbacksCount > 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.