2010-12-09 8 views
5

Tengo problemas para resolver cómo resolver el problema getElementsByClassName en IE. ¿Cómo implementaría mejor robert nyman (no puedo publicar el enlace porque mi representante solo tiene 1) resolución en mi código? ¿O una resolución jquery sería mejor? mi código esgetElementsByClassName Problema de resolución de IE

function showDesc(name) { 
var e = document.getElementById(name); 
//Get a list of elements that have a class name of service selected 
var list = document.getElementsByClassName("description show"); 

//Loop through those items 
for (var i = 0; i < list.length; ++i) { 
    //Reset all class names to description 
    list[i].className = "description"; 
} 

if (e.className == "description"){ 
    //Set the css class for the clicked element 
    e.className += " show"; 
} 
else{ 
    if (e.className == "description show"){ 
     return; 
    } 
}} 

y lo estoy usando en esta página dev.msmnet.com/services/practice-management para mostrar/ocultar la descripción de cada servicio (funciona en Chrome y FF). Algún consejo sería de gran aprecio.

+1

Una solución jQuery sería de hecho * * manera más fácil –

+0

uso de jQuery ... o cualquier otra estructura que se encarga de las cosas entre navegadores para usted. No reinventar la rueda. – Lee

Respuesta

2

Tenía curiosidad por ver lo que una versión de jQuery de su función se vería así, por lo que se le ocurrió esto:

function showDesc(name) { 
    var e = $("#" + name); 
    $(".description.show").removeClass("show"); 
    if(e.attr("class") == "description") { 
     e.addClass("show"); 
    } else if(e.hasClass("description") && e.hasClass("show")) { 
     return; 
    } 
} 
+0

¡esto funciona perfectamente! y si estoy en lo cierto, esto es más eficiente que mucho más eficiente que usar getElementsByTagName ("*") –

+0

Si quieres eficiencia, renuncia a la clase 'show' y utiliza jQuery para mostrar/ocultar. Ver mi respuesta a continuación. –

0

Puede reemplazar getElementsByClassName() con lo siguiente:

function getbyclass(n){ 
    var elements = document.getElementsByTagName("*"); 
    var result = []; 
    for(z=0;z<elements.length;z++){ 
    if(elements[z].getAttribute("class") == n){ 
     result.push(elements[z]); 
    } 
    } 
    return result; 
} 

A continuación, se puede utilizar de esta manera:

getbyclass("description") // Instead of document.getElementsByClassName("description") 
+0

También necesita manejar los atributos de clase que contienen cadenas de múltiples clases. – casablanca

+0

esto parece que sería terriblemente ineficiente si el documento tiene más que unos pocos elementos, o si llama a la función más de unas pocas veces. – Lee

+0

Es verdad, pero si acaba de escribir 'getbyclass (" one two ")' it * debería * recuperar los que tienen uno y dos. Si el OP necesita, puedo agregar un código para que funcione 100% tho – JCOC611

2

Esto debe soportar múltiples clases.

function getElementsByClassName(findClass, parent) { 

    parent = parent || document; 
    var elements = parent.getElementsByTagName('*'); 
    var matching = []; 

    for(var i = 0, elementsLength = elements.length; i < elementsLength; i++){ 

    if ((' ' + elements[i].className + ' ').indexOf(findClass) > -1) { 
     matching.push(elements[i]); 
    } 

    } 

    return matching; 

} 

También se puede pasar a uno de los padres, para que su búsqueda en DOM sea un poco más rápida.

Si desea getElementsByClassName('a c') para que coincida con HTML <div class="a b c" /> continuación, pruebe a cambiar así ...

var elementClasses = elements[i].className.split(/\s+/), 
    matchClasses = findClass.split(/\s+/), // Do this out of the loop :) 
    found = 0; 

for (var j = 0, elementClassesLength = elementClasses.length; j < elementClassesLength; j++) { 

    if (matchClasses.indexOf(elementClasses[j]) > -1) { 
     found++; 
    } 

} 

if (found == matchClasses.length) { 
    // Push onto matching array 
} 

Si desea que esta función sólo estará disponible si no existe ya, envuelva su definición con

if (typeof document.getElementsByClassName != 'function') { } 
1

Incluso más fácil solución jQuery:

$('.service').click(function() { 
    var id = "#" + $(this).attr('id') + 'rt'; 
    $('.description').not(id).hide(); 
    $(id).show(); 
} 

¿Por qué molestarse con una clase show si está utilizando jQuery?

1

Solía ​​implementar HTMLElement.getElementByClassName(), pero al menos Firefox y Chrome, solo encuentran la mitad de los elementos cuando esos elementos son muchos, en cambio uso algo así como (en realidad es una función más grande):

getElmByClass(clm, parent){ 
    // clm: Array of classes 
    if(typeof clm == "string"){ clm = [clm] } 
    var i, m = [], bcl, re, rm; 
    if (document.evaluate) { // Non MSIE browsers 
     v = ""; 
     for(i=0; i < clm.length; i++){ 
     v += "[contains(concat(' ', @"+clc+", ' '), ' " + base[i] + " ')]"; 
     } 
     c = document.evaluate("./"+"/"+"*" + v, parent, null, 5, null); 
     while ((node = c.iterateNext())) { 
      m.push(node); 
     } 
    }else{     // MSIE which doesn't understand XPATH 
     v = elm.getElementsByTagName('*'); 
     bcl = ""; 
     for(i=0; i < clm.length; i++){ 
      bcl += (i)? "|":""; 
      bcl += "\\b"+clm[i]+"\\b"; 
     } 
     re = new RegExp(bcl, "gi"); 
     for(i = 0; i < v.length; i++){ 
     if(v.className){ 
      rm = v[i].className.match(bcl); 
      if(rm && rm.length){  // sometimes .match returns an empty array so you cannot use just 'if(rm)' 
       m.push(v[i]) 
      } 
     } 
     } 
    } 
    return m; 
} 

creo que no habría una manera más rápida para recorrer sin XPath, porque RegExp son lentos (tal vez una función con .indexOf, que shuld ser probada), pero está funcionando bien

1

Heres uno pongo juntos, confiable y posiblemente el más rápido. Debería funcionar en cualquier situación.

function $class(className) { 
    var children = document.getElementsByTagName('*') || document.all; 
    var i = children.length, e = []; 
    while (i--) { 
     var classNames = children[i].className.split(' '); 
     var j = classNames.length; 
     while (j--) { 
      if (classNames[j] == className) { 
       e.push(children[i]); 
       break; 
      } 
     } 
    } 
    return e; 
} 
Cuestiones relacionadas