Foros del Web » Programando para Internet » Javascript »

indexOf v/s expresiones regulares

Estas en el tema de indexOf v/s expresiones regulares en el foro de Javascript en Foros del Web. Que tal gentes: Necesito hacer la siguiente consulta. Lo que estoy tratando de hacer (vía Javascript) es determinar si en el atributo CLASS de un ...
  #1 (permalink)  
Antiguo 24/08/2007, 20:25
 
Fecha de Ingreso: diciembre-2003
Mensajes: 1.583
Antigüedad: 20 años, 4 meses
Puntos: 13
indexOf v/s expresiones regulares

Que tal gentes:

Necesito hacer la siguiente consulta. Lo que estoy tratando de hacer (vía Javascript) es determinar si en el atributo CLASS de un elemento HTML se encuentra un determinado valor. Lo más lógico sería usar (elemento.className == "valor" ), pero eso no serviría si el atributo CLASS tiene más de un valor.

- Una alternativa sería usar expresiones regulares:

Código:
pattern = new RegExp("\b" + valor + "\b" );
result = pattern.test(elemento.className);
- Una segunda opción sería convertir el contenido del atributo CLASS en un Array, y luego recorrer el Array buscando si existe el valor buscado:

Código:
Array.prototype.indexOf = function(s) {
for (var x=0;x<this.length;x++){
if(this[x] == s)
return x;
}
return false;
}
arrClasses = els[i].className.split(' ' );
result = arrClasses.indexOf("valor" );

La duda que tengo es el rendimiento de c/u, especialemente cuando la busqueda se hace en varios elementos HTML simultáneamente. Ambas pruebas me reportan la misma velocidad, pero no sé con cual de los dos el browser necesitaría más recursos. ¿Alguna opinion?.
__________________
El conocimiento es libre: Movimiento por la Devolución
  #2 (permalink)  
Antiguo 25/08/2007, 08:08
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: indexOf v/s expresiones regulares

En este caso creo que no te merece la pena convertir el string que te devuelve className a un array. Lo más lógico (y eficiente) sería buscar en esa cadena lo que tú quieres con el indexOf() o con la ayuda de expresiones regulares y la función test().


Yo creo que el rendimiento lo tienes más eficiente en la función test() de las expresiones regulares, que te devuelve el boleano que buscas, menos código y más velocidad. Además nos quitamos el problema de si un nombre contiene a otro:
Imagínate dos clases de CSS, una que se llame soyrojo y otra nosoyrojo. Con el indexOf() si fueras a buscar soyrojo verías que lo encontraría en los elementos con esas dos clases: siempre se encuentra la cadena soyrojo en su className. Con las expresiones regulares no tienes ese problema gracias a los delimitadores de palabra "\b", que no podemos utilizar en indexOf().



Luego quizás tengamos otro problemita (solventable) como saber si una clase está delante de otra. El equivalente a indexOf() de las cadenas para usar expresiones regulares sería search(). Así que con search() puedes saber la posición que ocupa una clase en su className. Imagínate ésta declaración:
Código HTML:
<style type="text/css">
.rojopeq { color:red; font-size:10px !important; }
.grande { font-size:80px; }
</style>
------
<span id="elSpan" class="rojopeq grande">hola</span> 
En teoría grande suplanta los valores que haya podido dar rojopeq al span, luego el span debería quedar en rojo y a 80px. Lo que pasa es que tenemos un !important en la declaración de tamaño de rojopeq, luego el span queda rojo y pequeño. Si queremos saber si rojopeq está antes que grande en la declaración usaríamos el útil search().


Aqui te dejo el colmo de los colmos:
Código PHP:
<!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<
head>
<
meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<
meta name="Author" content="derkeNuke" />
<
title>Página nueva</title>
<
style type="text/css">
.
rojopeq color:redfont-size:10px !important; }
.
grande font-size:80px; }
</
style>
<
script type="text/javascript">

function 
tieneClase(elementoclase) {
    var 
pattern = new RegExp("\\b" clase "\\b");
    return 
pattern.test(elemento.className);
}
function 
estaAntesUnoQueDos(elementoclase1clase2) {
    var 
suClassname elemento.className;
    var 
pos1 suClassname.search(clase1);
    var 
pos2 suClassname.search(clase2);
    return 
pos1 pos2;                // no válido si pos1 fuera -1, comprobar que existen antes!
}

function 
soyRojoYpequeno(elemento) {
    if( 
tieneClase(elemento"rojopeq") && tieneClase(elemento"grande") ) {
        return 
estaAntesUnoQueDos(elemento"rojopeq""grande");
    }
    else
        return 
false;
}

</script>
</head>

<body>

<span id="elSpan" class="rojopeq grande" >hola</span> 
<br/>
<button type="button" onclick="alert( soyRojoYpequeno(document.getElementById('elSpan')) );" >
    ¿es el span rojo y pequeño?
</button>

</body>
</html> 

Aunque si quisieras más efectividad supongo que tieneClase(elemento, clase) debería ser tieneClases(elemento, clase1, clase2, clase3, ..., claseN), pero no creo que varíe demasiado el tiempo de ejecución. Supongo que no estaremos hablando de 10 000 elementos ¿verdad?




Bueno, espero que te aclare lo que te he comentado.
Un saludo.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:05.