2010-12-16 16 views
10

Preguntapase en la variable local a la función de devolución de llamada

¿Cómo puede una función de devolución de mantener una variable local de donde fue creado?

ejemplo simple

Estoy creando un reproductor de vídeo. Tendrá controles deslizantes para controlar la saturación, el contraste y el tono. Cuando el usuario juega con los controles deslizantes, necesita confirmar qué control deslizante cambió y en qué valor cambió. El problema es que el nombre del control deslizante es una variable local del alcance del creador de esta devolución de llamada onChange. ¿Cómo puede esta devolución de llamada conservar el nombre del control deslizante?

HTML

<div id="saturation"> 
<div class="track"></div> 
    <div class="knob"></div> 
</div> 
</div> 

<div id="contrast"> 
<div class="track"></div> 
    <div class="knob"></div> 
</div> 
</div> 

<div id="hue"> 
<div class="track"></div> 
    <div class="knob"></div> 
</div> 
</div> 

JS

var elements = [ 
'saturation', 
'contrast', 
'gamma' 
]; 

for(var i = 0; i < sliders.size(); i++) { 
new Control.Slider(
    $(elements[i]).down('.knob'), 
    $(elements[i]).down('.track'), { 
    onChange: function(value) { 
    // ERROR: elements[i] is undefined 
    alert(elements[i] + ' has been changed to ' + value); 
    } 
} 
} 

Respuesta

6

La misma variable, i - quién es el valor termina siendo 4 - está obligado a cada función se crea dentro del bucle. Se podría englobar la función en otra función que se llama en el lugar y pasar i como parámetro a la función:

for(var i = 0; i < sliders.size(); i++) { 
new Control.Slider(
    $(elements[i]).down('.knob'), 
    $(elements[i]).down('.track'), { 
    onChange: (function(inner_i) { function(value) { 
    alert(elements[inner_i] + ' has been changed to ' + value); 
    } })(i) 
} 
} 
+0

Esto me dio un error de sintaxis. – JoJo

+3

Creo que esto es lo correcto: onCambio: function() { return function (value) { alert (elementos [i] + value); } } (elementos [i]) – JoJo

+0

Al ver esto, pensé que el autor estaba siendo inteligente al omitir la declaración de devolución; Los lenguajes tipo Lisp simplemente devuelven la última expresión por defecto. Lamentablemente, javascript no es uno de ellos :( –

8

crear una copia de la variable para cada uno de devolución de llamada, puede hacer esto con una función anónima que se pasa en el valor:

for(var i = 0; i < sliders.size(); i++) { 

    (function(e) { // get a local copy of the current value 

     new Control.Slider(
      $(elements[e]).down('.knob'), 
      $(elements[e]).down('.track'), { 
      onChange: function(value) { 
      // ERROR: elements[e] is undefined 
      alert(elements[e] + ' has been changed to ' + value); 
      } 
     } 

    })(i); // pass in the current value 
} 

de esta manera no se hace referencia a los mismos i X veces.

0

Deja tus función dentro de un cierre de esta forma:


for(var i = 0; i < sliders.size(); i++) { 
(function(q){ 
new Control.Slider(
    $(elements[q]).down('.knob'), 
    $(elements[q]).down('.track'), { 
    onChange: function(value) { 
    // ERROR: elements[q] is undefined 
    alert(elements[q] + ' has been changed to ' + value); 
    } 
} 
})(i) 
} 
Cuestiones relacionadas