2009-06-03 16 views
6

Questa è una domanda che mi sono incentrato sull'espansione dell'evento JavaScript onchange di un elemento. Ho diversi elementi selezionati che condizionalmente avranno un evento onchange collegato a ciascuno di essi (quando cambiano a valori specifici, nasconde/nasconde determinati elementi). Voglio aggiungere o aggiungere condizionatamente un altro evento onchange in modo che impostino una variabile globale se cambiano senza modificare o disabilitare la funzione precedente già associata a essi. C'è un modo per "aggiungere" una funzione aggiuntiva o aggiungere più funzionalità a quella già esistente?Come espandere un evento onchange con JavaScript

Ecco quello che credo un esempio sarebbe come:

<select id="selectbox1"> 
    <option>...</option> 
    <option>...</option> 
</select> 

if (<certain conditions>) { 
    document.getElementById("selectbox1").onchange = function() { 
     //hides elements to reduce clutter on a web form ... 
    } 
} 
.... 
if (<other conditions>) { 
    document.getElementById("selectbox1").onchange = function2() { 
     //set global variable to false 
    } 
} 

In alternativa mi piacerebbe aggiungere semplicemente il 1-liner "impostato variabile globale su false" per la funzione originale.

+1

non riesco proprio a capire perché non si può fare condizionale ramo di destra nel gestore di eventi comuni, perché avete bisogno di espandersi? –

+0

Non è che non posso farlo, sarà un po 'una riprogettazione. Questa domanda riguardava come sarebbe possibile aggiungere funzionalità aggiuntive a una funzione. – Brian

risposta

9

Puoi imbrogliare semplicemente avendo una funzione composita che chiama le altre funzioni.

document.getElementById("selectbox1").onchange = function() { 
    function1(); 
    function2(); 
} 

È possibile anche usare il pattern Observer, descritto nel libro Pro JavaScript Design Patterns. Ho un esempio del suo uso in un articolo (here).

//– publisher class — 
function Publisher() { 
    this.subscribers = []; 
}; 

Publisher.prototype.deliver = function(data) { 
    this.subscribers.forEach(function(fn) { fn(data); }); 
}; 

//– subscribe method to all existing objects 
Function.prototype.subscribe = function(publisher) { 
    var that = this; 
    var alreadyExists = publisher.subscribers.some(function(el) { 
     if (el === that) { 
      return; 
     } 
    }); 

    if (!alreadyExists) { 
     publisher.subscribers.push(this); 
    } 
    return this; 
}; 
2

Si vuole guardare ai addEventListener() e attachEvent() funzioni (per i browser basati su Mozilla e IE, rispettivamente).

Dai un'occhiata ai documenti per addEventListener() e attachEvent().

var el = document.getElementById("selectbox1"); 

try { //For IE 
    el.attachEvent("onchange", function(){ code here.. }); 
} 
catch(e) { //For FF, Opera, Safari etc 
    el.addEventListener("change", function(){ code here.. }, false); 
} 

È possibile aggiungere più ascoltatori di ogni elemento, quindi, più di una funzione può essere chiamata quando l'evento.

2

Puoi usare jQuery? Ciò ti consentirà di associare/manipolare/separare gli eventi abbastanza facilmente. L'unico problema è che i gestori di eventi vengono attivati ​​nell'ordine in cui sono vincolati.

if (<certain conditions>) { 
    $("#selectbox1").bind("change", eventdata, function1); 
} 

if (<other conditions>) { 
    $("#selectbox1").bind("change", eventdata, function1); 
} 

E, puoi anche attivare gli eventi personalizzati, se le tue esigenze sono complesse. Ad esempio, invece di "interpretare" onChange, forse c'è un modo per attivare specificamente eventi personalizzati. Vedi lo last example sulla pagina di jQuery.

+0

Posso usare jQuery ma non l'ho mai usato prima. Evitando la curva di apprendimento per ora se possibile. – Brian

+1

Probabilmente c'è più di una curva di apprendimento per cercare di capire tutto il cross-browser e le varie interiora di JS e dei browser. E, jQuery è abbastanza facile da raccogliere, e vale il piccolo investimento ... – alphadogg

+0

jQuery sarà sicuramente il mio prossimo progetto! Voglio provare a riprenderlo nei prossimi mesi o due, ma prima di COB oggi vorrei ottenere una soluzione. – Brian

2

Se si utilizza jQuery si dovrebbe avere qualcosa di simile

<select id="selectbox1"> 
    <option>...</option> 
    <option>...</option> 
</select> 

if (<certain conditions>) { 
    $("#selectbox1").change(function() { 
     //hides elements to reduce clutter on a web form ... 
    }); 
} 
.... 
if (<other conditions>) { 
    $("#selectbox1").change(function() { 
     //set global variable to false 
    }); 
} 

Questa sarà per lo più prendersi cura di compatibilità del browser pure.

1

Attualmente esistono tre diversi metodi per la definizione dei gestori di eventi (una funzione che viene attivata quando viene rilevato un determinato evento): il metodo tradizionale, il metodo W3C e il metodo Microsoft.

Metodo tradizionale

Nel metodo tradizionale, i gestori di eventi sono definiti impostando l'on evento proprietà di un elemento in Javascript (come si sta facendo nel vostro codice di esempio), o impostando il su evento in un tag HTML (ad esempio <select onchange="...">). Sebbene questo sia il metodo più semplice da usare, il suo uso è generalmente disapprovato ora, perché come hai scoperto, è piuttosto rigido - non è facile aggiungere e rimuovere i gestori di eventi a un elemento che ha già un gestore di eventi collegato. Inoltre, non è più considerata una pratica appropriata mescolare javascript con HTML, ma piuttosto dovrebbe essere contenuto all'interno o caricato tramite un tag <script>.

W3C/metodi Microsoft

Il W3C (World Wide Web Consortium) e Microsoft sia definire i propri modelli di eventi. I due modelli funzionano essenzialmente allo stesso modo, ma usano diverse sintassi. Il modello Microsoft viene utilizzato in Internet Explorer e il modello W3C viene utilizzato in altri browser (Firefox, Opera, Safari, Chrome, ecc.). In entrambi i modelli, sono disponibili funzioni per aggiungere gestori di eventi (addEventListener per W3C, attachEvent per Microsoft) e rimuovere gestori di eventi (removeEventListener/detachEvent). Ciò consente di aggiungere e rimuovere dinamicamente gestori specifici a un elemento; nel tuo caso, potresti aggiungere il primo gestore in base alla prima condizione e il secondo in base alla seconda condizione. Il "problema" con questi metodi è che ce ne sono due, quindi è necessario utilizzare entrambi i metodi per garantire che il gestore di eventi sia registrato in tutti i browser (ci sono anche alcune sottili differenze tra i due modelli, ma quelle differenze non sono importanti per lo scopo di questa domanda). Infatti, se guardi, troverai un gran numero di funzioni "addEvent" che usano entrambi i metodi come necessario (e generalmente ricadono sul metodo tradizionale per i browser più vecchi). Ad esempio, un concorso è stato pubblicato sul blog QuirksMode nel 2005 per creare la migliore funzione "addEvent", il cui risultato (insieme alla funzione vincente) è possibile vedere here.

Inoltre, se si utilizza una libreria javascript come Prototype o jQuery, vengono fornite funzioni di gestione degli eventi incorporate che si prenderanno cura di quanto sopra per voi.

1

Mi sento come se potessi mancare qualcosa di importante nella tua domanda, ma questa soluzione più semplice non funzionerebbe per te?

Verificare semplicemente le condizioni all'interno di dell'evento onChange ed eseguire le azioni come desiderato. Sarebbe molto più più facile che dover dinamicamente aggiungere nuovamente/rimuovere eventListeners

document.getElementById("selectbox1").onchange = function() { 
    if (<certain conditions>) {  
    //hides elements to reduce clutter on a web form ... 
    } 
    if (<other conditions>) { ... } 
} 
Problemi correlati