2013-06-20 3 views
6

Sto cercando di utilizzare il mousetrap javascript plugin per gestire alcuni colpi di chiave in modo simile, così ho pensato di codificarle come segue:accesso variabili mutabili in una chiusura evento

var keys = [ 'b', 'i', 'u']; 
    for (var i=0; i < 3; ++i) { 
     var iKey = keys[i]; 
     var iKeyUpper = iKey.toUpperCase(); 

     Mousetrap.bind(
      [ 'command+' + iKey, 
       'command+' + iKeyUpper, 
       'ctrl+' + iKey, 
       'ctrl+' + iKeyUpper], 
      (function(e) { 
       console.log("you clicked: " + i); 
     })); 

    } 

Ma, ovviamente, i è modificabile. Tuttavia, non sono sicuro di come scrivere una chiusura in cui sono in competizione il parametro evento nella risposta. Suggerimenti su come gestire questa situazione?

+0

si desidera utilizzare l'evento nel gestore di attributi? Non ho capito bene "gareggiare" in questo contesto mi dispiace. – Edorka

+0

Mostraci cosa hai provato. Qual è stato il problema con il parametro dell'evento? La chiusura IEFE dovrebbe restituire la funzione di gestione che accetta il parametro 'e'. – Bergi

risposta

5

come scrivere una chiusura dove sono in competizione il parametro dell'evento nella risposta

Utilizzare una chiusura sia intorno a tutto il corpo del ciclo (come @dandavis) hanno dimostrato), o usarlo solo circa il gestore:

… 
    Mousetrap.bind(
     [ 'command+' + iKey, 
      'command+' + iKeyUpper, 
      'ctrl+' + iKey, 
      'ctrl+' + iKeyUpper], 
     (function(_i) { // of course you can use the name `i` again 
      return function(e) { 
       console.log("you clicked: " + _i); 
      }; 
     })(i) // and pass in the to-be-preserved values 
    ); 
4

è necessario avvolgere il variabile i in un ambito locale, in modo che non si sincronizza con la "i" nel ciclo for:

var keys = [ 'b', 'i', 'u']; 
    for (var i=0; i < 3; ++i) { 
     (function(i){ 
     var iKey = keys[i]; 
     var iKeyUpper = iKey.toUpperCase(); 

     Mousetrap.bind(
      [ 'command+' + iKey, 
       'command+' + iKeyUpper, 
       'ctrl+' + iKey, 
       'ctrl+' + iKeyUpper], 
      (function(e) { 
       console.log("you clicked: " + i); 
     })); 
     }(i)); 
    } 

l'altra alternativa è quella di utilizzare i metodi di matrice funzionale, che dato che usano le funzioni, hanno sempre il loro campo di applicazione, e forniscono il valore di elemento e l'indice elemento a voi intrinsecamente:

var keys = [ 'b', 'i', 'u']; 
    keys.map(function(iKey, i){ 
     var iKeyUpper = iKey.toUpperCase(); 

     Mousetrap.bind(
      [ 'command+' + iKey, 
       'command+' + iKeyUpper, 
       'ctrl+' + iKey, 
       'ctrl+' + iKeyUpper], 
      function(e) { 
       console.log("you clicked: " + i); 
     }); // end bind()  

    }); // end map() 

il 2 ° esempio funziona out of the box in IE9 +, ma è possibile farlo funzionare ovunque con un semplice pacchetto Array compatibile con il metodo Array, solitamente incluso negli spessori IE. .