Cuando solía requestAnimationFrame
hacer una animación nativa compatible con el siguiente código:
var support = {
animationFrame: window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame
};
support.animationFrame(function() {}); //error
support.animationFrame.call(window, function() {}); //right
Llamar directamente a la support.animationFrame
voluntad dará ...
TypeError no capturado: invocación ilegal
en cromo ¿Por qué?
fuente
myObj.myAlert('this is an alert');
es ilegal. El uso correcto esmyObj.myAlert.call(window, 'this is an alert')
. Lea las respuestas correctamente e intente comprenderlas.También puedes usar:
fuente
var realReplaceState = history.replaceState.bind(history);
.bind(localStorage)
no lo haga.bind(window)
.Cuando ejecuta un método (es decir, una función asignada a un objeto), dentro de él puede usar la
this
variable para referirse a este objeto, por ejemplo:Si asigna un método de un objeto a otro, su
this
variable se refiere al nuevo objeto, por ejemplo:Lo mismo sucede cuando asigna un
requestAnimationFrame
métodowindow
a otro objeto. Las funciones nativas, como esta, tienen protección incorporada contra su ejecución en otro contexto.Hay una
Function.prototype.call()
función que le permite llamar a una función en otro contexto. Solo tiene que pasarlo (el objeto que se usará como contexto) como primer parámetro de este método. Por ejemploalert.call({})
daTypeError: Illegal invocation
. Sin embargo,alert.call(window)
funciona bien, porque ahoraalert
se ejecuta en su alcance original.Si usa
.call()
con su objeto así:funciona bien, porque
requestAnimationFrame
se ejecuta en el alcance de enwindow
lugar de su objeto.Sin embargo, usar
.call()
cada vez que quiera llamar a este método, no es una solución muy elegante. En cambio, puedes usarFunction.prototype.bind()
. Tiene un efecto similar.call()
, pero en lugar de llamar a la función, crea una nueva función que siempre se llamará en el contexto especificado. Por ejemplo:El único inconveniente
Function.prototype.bind()
es que es parte de ECMAScript 5, que no es compatible con IE <= 8 . Afortunadamente, hay un polyfill en MDN .Como probablemente ya haya descubierto, puede usar
.bind()
para ejecutar siemprerequestAnimationFrame
en contexto dewindow
. Su código podría verse así:Entonces puedes simplemente usar
support.animationFrame(function() {});
.fuente