2014-12-15 19 views
6

Ho ereditato alcuni JS (che non posso cambiare), che spara una serie di eventi:Osservare un evento JS, quando si conosce solo PARTE del nome dell'evento?

jQuery(document).trigger('section:' + section); 
// where "section" changes dynamically 

E voglio osservare per tutti questi eventi, e analizzare il valore per section, e fare qualcosa di diverso a seconda del contenuto.

Se non ha cambiato ho potuto fare questo:

jQuery(document).on('section:top', doStuff); 

ma come faccio osservare un evento se conosco solo la prima parte di questo nome dell'evento?

+0

Non puoi! Il 'trigger' di jQuery non memorizza gli eventi da nessuna parte, cosa che di solito accade quando i gestori di eventi sono vincolati, quindi, se viceversa, probabilmente lo potresti fare. Ovviamente tutto è possibile, puoi analizzare tutto il javascript e cercare le chiamate a 'trigger', ma è semplicemente sbagliato. – adeneo

+0

Penso che tu sia sfortunato, quelli sono fondamentalmente eventi diversi ... Quella parte dinamica dell'evento avrebbe dovuto essere un argomento per l'evento. 'jQuery (document) .trigger ('section', section);' Non hai modo di sapere quali sono tutte le sezioni valide? Se è così, puoi fare '$(). On ('sezione: sezione superiore: sezione inferiore: sezione destra: sinistra')' –

+0

http://stackoverflow.com/questions/26225987/one-listener-for-all- events-in-jquery-event-namespace/26227362 # 26227362 – guest271314

risposta

0

Ecco quello che ho finito per fare.

è una combinazione della soluzione di Juan Mendes, e utilizzando un method from the prototype library

Originariamente, c'era una funzione che correva questo codice:

myObject.adjustSection(section) { 
    jQuery(document).trigger('section:' + section); 
} 
// I couldn't edit this function 

Così ho esteso la funzione con il metodo di prototipo wrap, dato che il mio progetto utilizzato prototipo e jQuery.

// My custom function wrapper 
// extend adjustSection to include new event trigger 
myObject.prototype.adjustSection = myObject.prototype.adjustSection.wrap(
    function(parentFunction, section) { 
     // call original function 
     parentFunction(section); 
     // fire event w/section info 
     jQuery(document).trigger({ 
      type: 'adjustSection', 
      section: section 
     }); 
    } 
); 

Quindi, esegue l'originale, ma genera anche il mio evento personalizzato che include le informazioni sulla sezione.

Ora, posso fare questo per osservare l'evento e ottenere il tipo di sezione:

jQuery(document).on('adjustSection', function(event) { 
    event.section; // contains the section I need 
}); 

Naturalmente, questo significa che devo utilizzare sia prototipo e jQuery all'interno della stessa portata, che non è il cosa migliore del mondo. Ma ha funzionato.

+0

Perché non è possibile modificare 'myObject.prototype.adjustSection' nella sua posizione originale? Lo farei solo per le librerie di terze parti in cui apportare modifiche al loro codice può rendere davvero difficile l'aggiornamento. –

+0

Buon punto, ma non ho accesso per modificare la dichiarazione del metodo originale. –

4

Purtroppo non è possibile ascoltare tutti gli eventi nello stile $().on('section:*'). Se è possibile modificare il codice, vorrei fare le seguenti operazioni:

jQuery(document).trigger({ 
    type: 'section', 
    section: section 
}); 

Poi si ascolta per esso e non c'è bisogno di analizzare nulla

jQuery(document).on('section', function(e){ 
    if (e.section === 'top') { 
     // Something happened to the top section 
    } 
}); 

Se si vuole ridurre al minimo le modifiche al codice, lascia lì il vecchio evento, in questo modo il codice esistente non verrà modificato.

Un approccio diverso sarebbe utilizzare gli spazi dei nomi di eventi.

jQuery(document).trigger('section.' + section); 

jQuery(document).on('section', function(e){ 
    if (e.namespace === 'top') { 
     // Something happened to the top section 
    } 
}); 

Io, invece, preferisco il primo approccio, perché gli spazi dei nomi degli eventi sono più comunemente utilizzati per uno scopo diverso: per essere in grado di rimuovere gli eventi senza essere costretti a mantenere un riferimento al gestore stesso. Vedi http://css-tricks.com/namespaced-events-jquery/ e http://ejohn.org/apps/workshop/adv-talk/#13. Preferisco usare gli stili a cui altri sviluppatori sono abituati, se fanno il lavoro.

+0

Ottima risposta, ho usato una parte di questo nella mia soluzione finale. Grazie! –

0

Io non sono davvero sicuro di vostro caso d'uso, ma si potrebbe sovrascrivere $.fn.trigger metodo:

(function ($) { 
 
    var oldTrigger = $.fn.trigger; 
 
    $.fn.trigger = function() { 
 
     if (arguments[0].match(/^section:/)) { 
 
      doStuff(arguments[0].split(':')[1]); 
 
     } 
 
     return oldTrigger.apply(this, arguments); 
 
    }; 
 
})(jQuery); 
 
var section = "top"; 
 
jQuery(document).trigger('section:' + section); 
 

 
function doStuff(section) { 
 
    alert(section); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>