2011-12-07 15 views
6

È possibile associare una funzione a un'altra funzione su invoke? Quindi, ad esempio, sarebbe qualcosa di simile:Evento chiamato in funzione in JS?

function a(){...} 
function b(){...} 
b.bind("onInvoke","a"); 

Così, quando viene chiamato b, viene automaticamente chiamato anche a.


MODIFICA: OK OK, per chiarire, questa non è una domanda sul concatenamento. L'idea è quella di trovare un modo elegante per legare eventi. Osservare il normale modo "non elegante" con il normale richiamo della funzione:

function handler(){...} 
function caller1(){handler(); ...} 
function caller2(){handler(); ...} 
function caller2(){handler(); ...} 
// More callers all over your website everywhere else 

Che funziona? Ma cosa succede se ho un chiamante dappertutto? È difficile organizzare o cambiare le cose.

Osservare ora la soluzione superiore! (Se uno esiste)

function handler(){...} 
// Caller make no reference to handler on creation 
function caller1(){...} 
function caller2(){...} 
function caller3(){...} 
// Caller function are still all over the place, all over your website 
// Event handler registered later in one location here, doesn't matter where they are phsically 
caller1.bind("onInvoke",handler); 
caller2.bind("onInvoke",handler); 
caller3.bind("onInvoke",handler); 

così molto simile a un normale HTML - JQuery registrazione dell'evento. Non scrivi onClick su tutte le immagini su cui l'utente può fare clic (che sono dappertutto), sarebbe troppo difficile organizzarlo! Basta scrivere uno semplice

$("img").bind("onClick",click_handler); 

per l'intero sito. Questo è il jist di ciò che sto cercando, ad eccezione delle funzioni JS.

Spero che chiarisca le cose.


MODIFICA 2: È necessario lavorare con IE7 !!! JavaScript 1.8.5 è fantastico e tutto, ma niente lo supporta ora.

+0

possibile duplicato (http://stackoverflow.com/questions/3406467/can-i-intercept-a-function-called-directly) –

+0

@AndyE Ho la sensazione che l'OP sia più interessata a una soluzione per chiamare automaticamente le funzioni in sequenza. – Peter

+0

@Peter: non ne sono così sicuro. * "Così, quando viene chiamato b, viene automaticamente chiamato anche a." * - c'è potenzialmente una differenza nell'ordine di esecuzione (questa domanda potrebbe volere che 'a' venga invocato dopo' b', ad esempio), ma la premessa tra i due le domande sembrano essere le stesse; * "quando viene chiamata una funzione, chiama questa altra funzione" *. Potrei sbagliarmi, ma spetta all'OP fare una chiara distinzione tra le due domande :-) –

risposta

2

Ci sono varie soluzioni a seconda di quanto si vuole architetto. Un approccio semplice e flessibile è quello di creare una funzione di utilità concatenamento:

function chain() { 
    var args = arguments; 
    return function() { 
     // loop through arguments and invoke all functions 
     for(var i = 0; i < args.length; i++) { 
     if(typeof args[i] == "function") 
      args[i](); 
     } 
    } 
} 

Ciò sta facendo sta tornando una nuova funzione che chiamerà le funzioni previste in sequenza.Utilizzare in questo modo: [? Posso intercettare una funzione chiamata direttamente]

var myChain = chain(b, a); 
myChain(); 
+0

Ciao Peter, questa soluzione è buona per concatenare ma non utile nella situazione in cui mi trovo attualmente. – Bill

+0

@YongkeBillYu: In realtà, risolve il tuo problema. Basta fare 'caller1 = chain (handler, caller1)' – hugomg

+0

Sì, hai ragione, è davvero una buona soluzione. – Bill

0

JavaScript 1.8.5/ECMAScript 5 effettivamente definire un bind function, ma non fa ciò che si descrive in precedenza; consente di specificare quale sarà il contesto this quando viene richiamato e, facoltativamente, consente di codificare determinati argomenti-curry.

+0

Suppongo che non esista attualmente molto supporto per browser per JS 1.8.5, giusto? – Bill

4

È possibile farlo con un approccio orientato all'aspetto. Ecco un semplice esempio:

Fissare la chiamata a un() di funzionare B():

var _b = b; 
b = function(){ 
    _b(); 
    a(); 
} 

Ora chiamare b():

b(); 

vederlo in azione qui: http://jsfiddle.net/eZ9wJ/

+0

In questo esempio b è una variabile globale. Dovresti sempre usare 'var' per definire le variabili; –

+2

Sto sovrascrivendo il riferimento alla funzione globale b() che Yongke ha già definito nel codice nella sua domanda. Per richiamare la funzione a() su qualsiasi chiamata a b(), devi sovrascriverla nello stesso ambito in cui è stata definita la funzione originale. Ovviamente questo è solo un esempio semplificato. In un esempio reale, non consiglierei di definire la funzione nell'ambito globale. – Simon

+2

Una cosa da tenere a mente qui è che qualsiasi oggetto che era inizialmente trattenuto su un riferimento a 'b' non verrà aggiornato; quindi questo approccio potrebbe rompersi. Va sottolineato che stiamo ancora chiamando una funzione * nuova * qui, anche se la memorizziamo nella variabile originale. – Peter

Problemi correlati