2008-11-10 11 views
17

Tengo algo de código haciendo esto:getElementsByName en IE7

var changes = document.getElementsByName(from); 
for (var c=0; c<changes.length; c++) { 
    var ch = changes[c]; 
    var current = new String(ch.innerHTML); 
    etc. 
} 

Esto funciona bien en FF y Chrome, pero no en IE7. Presumiblemente porque getElementsByName no funciona en IE. ¿Cuál es la mejor solución?

Respuesta

17

En caso de que no sabe por qué esto no está funcionando en el IE, aquí es the MSDN documentation on that function:

Cuando se utiliza el método getElementsByName, todos los elementos del documento que tiene el atributo de nombre especificado o ID el valor del atributo se devuelve.

Los elementos que admiten tanto el atributo NAME como el atributo ID se incluyen en la colección devuelta por el método getElementsByName, pero los elementos con un NAME expando no se incluyen en la colección; por lo tanto, este método no se puede usar para recuperar etiquetas personalizadas por nombre.

Firefox permite getElementsByName() recuperar elementos que usan un NAME expando, por lo que funciona. Si eso es algo bueno o no, puede estar en debate, pero esa es la realidad.

Por lo tanto, una opción es utilizar el método DOM getAttribute() para solicitar el atributo NAME y luego probar el valor para ver si es lo que desea y, de ser así, agregarlo a una matriz. Esto requeriría, sin embargo, iterar sobre todos los nodos en la página o al menos dentro de una subsección, que no sería la más eficiente. Puede restringir esa lista de antemano usando algo como getElementsByTagName() quizás.

Otra forma de hacerlo, si tiene el control del código HTML de la página, es otorgando a todos los elementos de interés un Id que varía solo por número, p. Ej.:

<div id="Change0">...</div> 
<div id="Change1">...</div> 
<div id="Change2">...</div> 
<div id="Change3">...</div> 

Y luego tener JavaScript así:

// assumes consecutive numbering, starting at 0 
function getElementsByModifiedId(baseIdentifier) { 
    var allWantedElements = []; 
    var idMod = 0; 
    while(document.getElementById(baseIdentifier + idMod)) { // will stop when it can't find any more 
     allWantedElements.push(document.getElementById(baseIdentifier + idMod++)); 
    } 
    return allWantedElements; 
} 

// call it like so: 
var changes = getElementsByModifiedId("Change"); 

Eso es un truco, por supuesto, pero sería hacer el trabajo que necesita y no sea demasiado ineficiente en comparación con algunos otros cortes.

Si está utilizando un framework/kit de herramientas de JavaScript de algún tipo, sus opciones son mucho mejores, pero no tengo tiempo para entrar en esos detalles a menos que indique que está utilizando uno. Personalmente, no sé cómo vive la gente sin uno, ahorran tanto tiempo, esfuerzo y frustración que no puede pagar y no para usar uno.

+0

Tomar la documentación de MSDN como la "implementación correcta" parece una postura extraña. El nombre no es ID. MSFT lo entendió mal, muy mal. Uno puede argumentar qué elementos deben tener nombres, pero devolver un elemento que no tiene un nombre es simplemente una tontería. (Se rumorea que esto está arreglado en el modo estándar de IE8) – scunliffe

+0

La documentación de MSDN * es * la implementación correcta para IE 7: el cartel original decía que IE7 había roto su código, en caso de que no leyera su publicación. El OP aplicaba el atributo de nombre como un atributo expando en una etiqueta para la que no se permite el nombre, por lo que IE no lo devolvió, según la documentación. –

+3

Lo siento, pero ** ¿dónde ** en la pregunta de OP hay * alguna mención * de * configuración * el nombre? Solo veo el código que indica que el OP intentaba iterar sobre los elementos recuperados utilizando 'document.getElementsByName (name)'. Todavía apoyo mi declaración de que la implementación de '.getElementsByName (name)' es incorrecta en IE (en todas las versiones heredadas). – scunliffe

4

Hay un par de problemas:

  1. IE es de hecho confuso id="" con name=""
  2. name="" no está permitido en <span>

Para solucionar, sugiero:

  1. Cambiar todo name="" a class=""
  2. cambiar el código de la siguiente manera:

-

var changes = document.getElementById('text').getElementsByTagName('span'); 
for (var c=0; c<changes.length; c++) { 
var ch = changes[c]; 

if (ch.className != from) 
continue; 

var current = new String(ch.innerHTML); 
+0

Bien, gracias. La página está aquí (http://lwww.dege.ukfsn.org/encrypt/decode.php) es una ilustración simple de descifrado de códigos a través del análisis de frecuencia de letras. Es posible que deba presionar la pestaña cuando ingrese una letra en IE. En FF, un retorno también lo hace. – sa386

+1

gracias. cambiar a clase es una buena solución – sa386

+0

Al principio no creía que esto funcionara en mi IE 11 ni en IE 8, pero mi mayúscula era incorrecta en el 'Id' en .getElementById(). ¡He cometido ese error tantas veces! Pero después de corregir * mis propios * errores, esto funcionó muy bien tanto en IE 8 como en IE 11. ¡Gracias por la gran solución! ¡si solo el IE wud funciona tan bien como otros navegadores! Espero que Edge no sea tan malo. El tiempo dirá. –

1

getElementsByName es compatible con IE, pero hay bichos. En particular, devuelve elementos cuya 'id' coincide con el valor dado, así como con 'nombre'. No puedo decir si ese es el problema que tiene sin un poco más de contexto, código y mensajes de error reales.

En general, getElementsByName probablemente es mejor evitarlo, porque el atributo 'nombre' en HTML tiene varios propósitos superpuestos que pueden confundir. Usar getElementById es mucho más confiable. Cuando trabaje específicamente con campos de formulario, puede usar form.elements [name] de manera más confiable para recuperar los campos que está buscando.

+0

getElementsByName es realmente útil si está * solo * buscando campos de formulario para los cuales un atributo NAME es realmente parte de la especificación W3C. Dicho esto, sería raro que alguna vez lo usara realmente. –

2

No es muy común encontrar elementos usando la propiedad NAME. Yo recomendaría cambiar a la propiedad de ID.

Sin embargo, puede encontrar los elementos con un nombre específico usando jQuery:

$("*[name='whatevernameYouWant']"); 

Esto devolverá todos los elementos con el nombre dado.

+4

Me preguntaba cuándo iba a aparecer la respuesta jQuery obligatoria, por lo general caen dentro de unos segundos de una publicación de JavaScript. –

+0

eso es porque escribir jQuery es mucho más rápido que javascript normal :) –

1

que he tenido éxito en el uso de un envoltorio para devolver una matriz de los elementos. Funciona en IE 6 y 7 también. Tenga en cuenta que no es 100% exactamente lo mismo que document.getElementsByName, ya que no es un NodeList. Pero para lo que necesito, que es ejecutar un bucle for en una serie de elementos para hacer cosas simples como configurar .disabled = true, funciona bastante bien.

Aunque esta función todavía usa getElementsByName, funciona si se usa de esta manera. Ver por ti mismo.

function getElementsByNameWrapper(name) { 
    a = new Array(); 

    for (var i = 0; i < document.getElementsByName(name).length; ++i) { 
    a.push(document.getElementsByName(name)[i]); 
    } 

    return a; 
} 
1

Solución

   var listOfElements = document.getElementsByName('aName'); // Replace aName with the name you're looking for 
      // IE hack, because it doesn't properly support getElementsByName 
      if (listOfElements.length == 0) { // If IE, which hasn't returned any elements 
       var listOfElements = []; 
       var spanList = document.getElementsByTagName('*'); // If all the elements are the same type of tag, enter it here (e.g.: SPAN) 
       for(var i = 0; i < spanList.length; i++) { 
        if(spanList[i].getAttribute('name') == 'aName') { 
         listOfElements.push(spanList[i]); 
        } 
       } 
      }