2010-07-27 49 views
10

como dice el título, me sigo "indefinido" cuando trato de obtener el atributo id de un elemento, básicamente lo que quiero hacer es reemplazar un elemento con un cuadro de entrada cuando el valor es "otro".

Aquí está el código:

function showHideOther(obj){ 

    var sel = obj.options[obj.selectedIndex].value; 
    var ID = $(this).attr("id"); 

    alert(ID); 


    if(sel=='other'){ 

     $(this).html("<input type='text' name='" + ID + "' id='" + ID + "' />"); 

    }else{ 
     $(this).css({'display' : 'none'}); 
    } 
} 

El HTML:

  <span class='left'><label for='race'>Race: </label></span> 
      <span class='right'><select name='race' id='race' onchange='showHideOther(this);'> 
      <option>Select one</option> 
      <option>one</option> 
      <option>two</option> 
      <option>three</option> 
      <option value="other">Other</option> 
      </select> 
      </span> 

Es probablemente algo pequeño que no estoy notando, ¿qué estoy haciendo mal?

¡Gracias por adelantado!

Respuesta

2

Debido a la forma en que la función se llama (es decir, como una simple llamada a una variable de función), this es el objeto global (para la que window es un alias en los navegadores). Use el parámetro obj en su lugar.

Además, la creación de un objeto jQuery y el uso de su método attr() para obtener una identificación de elemento es ineficiente e innecesario. Simplemente use la propiedad id del elemento, que funciona en todos los navegadores.

function showHideOther(obj){ 
    var sel = obj.options[obj.selectedIndex].value; 
    var ID = obj.id; 

    if (sel == 'other') { 
     $(obj).html("<input type='text' name='" + ID + "' id='" + ID + "' />"); 
    } else { 
     $(obj).css({'display' : 'none'}); 
    } 
} 
0

¿A qué esperas que se refiera $(this)?

¿Quieres decir sel.attr("id"); quizás?

0

En el contexto función "este" no es en referencia al elemento de selección, sino a la propia página

  • Cambio var ID = $(this).attr("id"); a var ID = $(obj).attr("id");

Si obj es ya una jQuery Object, simplemente elimine el $() a su alrededor.

5

usando this en una función, cuando debería usar el parámetro.

Sólo se utiliza $ (este) en devoluciones de llamada ... de selecciones como

$('a').click(function() { 
    alert($(this).href); 
}) 

En el cierre, la forma correcta (usando el ejemplo de código) sería la de hacer esto

obj.attr('id');

+1

"esto" siempre se referirá al objeto en el que está trabajando. Y puede ser utilizado en cualquier lugar. Por supuesto, si sabes lo que estás haciendo. – GerManson

+1

en lugar de '$ (this) .href', puede simplemente' this.href' y también 'obj.id' ... btw,' obj.attr ('id'); 'debe ser' $ (obj) .attr ('id'); 'basado en OP ... – Reigel

9

Cambio

var ID = $(this).attr("id"); 

a

var ID = $(obj).attr("id"); 

También se puede cambiar a usar jQuery controlador de eventos:

$('#race').change(function() { 
    var select = $(this); 
    var id = select.attr('id'); 
    if(select.val() == 'other') { 
     select.replaceWith("<input type='text' name='" + id + "' id='" + id + "' />"); 
    } else { 
     select.hide(); 
    } 
}); 
+0

obj parece que ya es un objeto jQuery. – efritz

+0

Si se pasa desde el atributo onchange = "" será una referencia a HTMLElement, no a un objeto jQuery – fantactuka

1

Retire la inline event handler y hacerlo completamente discreta, como

​$('​​​​#race').bind('change', function(){ 
    var $this = $(this), 
     id = $this[0].id; 

    if(/^other$/.test($(this).val())){ 
     $this.replaceWith($('<input/>', { 
      type: 'text', 
      name: id, 
      id: id 
     })); 
    } 
});​​​ 
+0

+1 para un enfoque discreto! –

+0

¿Por qué ...........? –

+0

Es mucho más limpio y fácil de mantener – fantactuka

0

recomiendo a leer más información sobre el this keyword .

No puede esperar que "this" seleccione la etiqueta "select" en este caso.

Lo que quiere hacer en este caso es usar obj.id para obtener la identificación de la etiqueta de selección.

2

También podría escribir su función completa como una extensión jQuery, por lo que podría hacer algo similar a `$ ('# element'). ShowHideOther();

(function($) { 
    $.extend($.fn, { 
     showHideOther: function() { 
      $.each(this, function() { 
       var Id = $(this).attr('id'); 
       alert(Id); 

       ... 

       return this; 
      }); 
     } 
    }); 
})(jQuery); 

No es que responda a su pregunta ... Solo algo para pensar.

0

Usted puede hacer

onchange='showHideOther.call(this);'

en lugar de

onchange='showHideOther(this);'

Pero entonces también es necesario para reemplazar obj con this en la función.