2012-02-07 27 views
14

Digamos que tengo window.open (sin parámetro de nombre), disperso en mi proyecto y quiero cambiar la implementación para que, donde sea que no se especifique el nombre, especifique un nombre predeterminado.¿Cómo sobrescribir la funcionalidad window.open?

Lo que quiero hacer al respecto es enganchar mi propio método a window.open para que cada vez que se ejecute window.open llame internamente a mi propio método, que luego llamará a window.open (con el parámetro name).

¿Es posible a través de Javascript? ¿Habrá algún problema de dependencia circular en esto, es decir, window.open llamando a mi función personalizada que a su vez llama de nuevo a la función window.open?

P.s. En términos simples, lo que quiero hacer es anular la funcionalidad window.open.

Respuesta

26

Para evitar llamadas circulares, necesita esconder la función original window.open en una variable.

Una buena manera (que no contamina el espacio de nombre global) es utilizar un cierre. Pase la función original window.open a una función anónima como argumento (llamada open a continuación). Esta función anónima es una fábrica para su función de gancho. Su función de enlace está obligado permanentemente a la función original window.open mediante el argumento open:

window.open = function (open) { 
    return function (url, name, features) { 
     // set name if missing here 
     name = name || "default_window_name"; 
     return open.call(window, url, name, features); 
    }; 
}(window.open); 
+0

¿Puede explicar lo que está sucediendo aquí? No estoy muy versado con JS, me temo. –

+0

Lo expliqué con una actualización anterior. No creo poder entrar en detalles más profundos que esto. Recomiendo leer sobre: ​​1. Los ámbitos de función y los métodos de llamada/aplicación. 2. Patrones de módulos. –

+0

Da este error JS: error de tiempo de ejecución de Microsoft JScript: el objeto no admite la propiedad o el método 'call' –

4

P.s. In simple terms what I want to do is override the window.open functionality.

var orgOpen = window.open; 

window.open = function (url, windowName, windowFeatures) { 
    alert("Overrided!"); 
    return orgOpen(url, windowName, windowFeatures); 
} 

window.open("http://www.stackoverflow.com"); 
+2

1. Contamina el espacio de nombres global. 2. La función de enganche no usa ningún argumento. 3. La función de enganche no devuelve el nuevo objeto de ventana. 4. ¿Cómo funcionó esto? –

+1

No me importaría mucho sobre la contaminación del espacio de nombres. – georg

9

Sé que esta respuesta es un poco tarde, pero sentí que una solución más general puede ser útil para otras personas (tratando de anular otros métodos)

function wrap(object, method, wrapper){ 
    var fn = object[method]; 

    return object[method] = function(){ 
     return wrapper.apply(this, [fn.bind(this)].concat(
      Array.prototype.slice.call(arguments))); 
    }; 
}; 

//You may want to 'unwrap' the method later 
//(setting the method back to the original) 
function unwrap(object, method, orginalFn){ 
    object[method] = orginalFn; 
}; 

//Any globally scoped function is considered a 'method' of the window object 
//(If you are in the browser) 
wrap(window, "open", function(orginalFn){ 
    var originalParams = Array.prototype.slice.call(arguments, 1); 
    console.log('open is being overridden'); 
    //Perform some logic 
    //Call the original window.open with the original params 
    orginalFn.apply(undefined, originalParams); 
}); 
+1

Manera genérica limpia agradable de enganchar la función de un objeto –

Cuestiones relacionadas