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

时间:2016-11-03 15:39:53

标签: javascript requestanimationframe

如果某个函数传递给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."

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

3 个答案:

答案 0 :(得分:2)

目前无法在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);

答案 1 :(得分: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."




答案 2 :(得分: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

不幸的是,无法保证使用PHP Fatal error: Uncaught exception 'Symfony\\Component\\Debug\\Exception\\ContextErrorException' with message 'Catchable Fatal Error: Argument 8 passed to Sonata\\MediaBundle\\Provider\\ImageProvider::__construct() must implement interface Imagine\\Image\\ImagineInterface, none given, called in 的任何人都不会将其称为传递值。