Foros del Web » Programando para Internet » Javascript »

SOLUCIONADO: 'className' es nulo o no es un objeto

Estas en el tema de SOLUCIONADO: 'className' es nulo o no es un objeto en el foro de Javascript en Foros del Web. Buenas, tengo este código (lo pongo completo por si lo quieren probar): Código: <!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"> <head> <meta ...
  #1 (permalink)  
Antiguo 01/08/2007, 15:11
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 9 meses
Puntos: 535
De acuerdo SOLUCIONADO: 'className' es nulo o no es un objeto

Buenas, tengo este código (lo pongo completo por si lo quieren probar):

Código:
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Manipular una tabla</title>
<script type="text/javascript">
function prepara_tabla(){
	var tabla = document.getElementById('mi_tabla');
	var filas = tabla.rows;
	for(i = 0; i < filas.length; i++){
		la_celda = filas[i].cells[filas[i].cells.length - 1];
		if(la_celda.nodeName.toLowerCase() == 'td'){
			filas[i].setAttribute('class', 'az_fila_origen');
		}
	}
	crea_copias('az_fila_origen');
}


function crea_copias(laClase){
	var filas = document.getElementById('mi_tabla').getElementsByTagName('tr');
	var cantidad_filas = filas.length;
	for(i = 0; i < (cantidad_filas * 2 - 1); i++){
alert('i vale ' + i + ' y tiene que llegar a ' + ((cantidad_filas * 2 - 1) - 1) + '\nLa clase se llama: ' + filas[i].className);
		if(filas[i].className == laClase){
			la_celda = filas[i].cells[filas[i].cells.length - 1];
			nuevo_row = document.createElement('tr');
				nuevo_cell = document.createElement('td');
				nuevo_cell.setAttribute('colspan', '5');
					nuevo_cell_texto = document.createTextNode(la_celda.textContent);
				nuevo_cell.appendChild(nuevo_cell_texto);
			nuevo_row.style.display = 'none';
			nuevo_row.setAttribute('class', 'azNuevaFila')
			nuevo_row.appendChild(nuevo_cell);
			la_celda.textContent = '';
			nueva_imagen = document.createElement('img');
			nueva_imagen.setAttribute('src', 'images/flecha_abajo.gif');
			nueva_imagen.onclick = function(){muestra_oculta(this);};
			nueva_imagen.onmouseover = function(){this.style.cursor = 'pointer';};
			la_celda.appendChild(nueva_imagen);
			// comienza código de caricatos para emular un insertAfter \\
			if(filas[i].parentNode.lastChild == filas[i]){
				filas[i].parentNode.appendChild(nuevo_row);
			}
			else{
				filas[i].parentNode.insertBefore(nuevo_row, filas[i].nextSibling);
			}
			// finaliza código de caricatos para emular un insertAfter \\
		}//if
	}
}

function muestra_oculta(elemento){
	la_fila = elemento.parentNode.parentNode.nextSibling;
	la_fila.previousSibling.style.borderLeft = '5px solid #666666;';
	if(la_fila.style.display == 'none'){
		la_fila.style.display = 'table-row';
		elemento.src = 'images/flecha_arriba.gif';
	}
	else{
		la_fila.style.display = 'none';
		la_fila.previousSibling.style.borderLeft = 'inherit';
		elemento.src = 'images/flecha_abajo.gif';
	}
}

window.onload = prepara_tabla;
</script>
<style type="text/css">
<!--
#mi_tabla {
	border-collapse: collapse;
	font-family: Georgia, "Times New Roman", Times, serif;
	width: 650px;
}

#mi_tabla th {
	background: #CCCCCC;
}

#mi_tabla td, #mi_tabla th {
	border-collapse: collapse;
	border: 1px solid #666666;
	padding: 5px;
}

.azNuevaFila{
	background: #F7F7F7;
	color: #333333;
	border-bottom: 5px solid #666666;
	border-left: 5px solid #666666;
	font-size: 12px;
}
-->
</style>
</head>

<body>
<h1>Manipular una tabla</h1>
<table id="mi_tabla" cellspacing="1">
  <tr>
    <th scope="col">Encabezado 1</th>
    <th scope="col">Encabezado 2</th>
    <th scope="col">Encabezado 3</th>
    <th scope="col">Encabezado 4</th>
    <th scope="col">Encabezado 5</th>
  </tr>
  <tr>
    <td>Dato 1.1</td>
    <td>Dato 1.2</td>
    <td>Dato 1.3</td>
    <td>Dato 1.4</td>
    <td>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris orci  turpis, porta id, varius vel, cursus sit amet, enim. Suspendisse dui  lectus, dapibus quis, vestibulum in, auctor ut, sapien. In aliquet  purus sed ligula aliquet sagittis. Nulla sodales. In scelerisque. Nulla  ultrices dignissim erat. Praesent lorem tellus, dignissim ac, ultrices  in, ullamcorper sed, dolor. Nulla facilisi. Donec luctus, metus eu  eleifend venenatis, nibh lacus lacinia ante, eget lobortis neque ante  non dui. Nam tristique. Fusce sagittis diam eu augue. Duis dui massa,  volutpat vel, molestie id, mollis consequat, est. Praesent dapibus  ultrices lacus. Aliquam pulvinar tellus id nulla. Suspendisse lacinia  nulla in leo. Vestibulum ante ipsum primis in faucibus orci luctus et  ultrices posuere cubilia Curae; Suspendisse et turpis in mi lacinia  aliquet. Vivamus diam lorem, convallis quis, egestas vel, pretium id,  lorem.</td>
  </tr>
  <tr>
    <td>Dato 2.1</td>
    <td>Dato 2.2</td>
    <td>Dato 2.3</td>
    <td>Dato 2.4</td>
    <td>Etiam tristique vehicula lacus. Mauris velit nulla, laoreet sit amet,  dapibus ac, venenatis et, leo. Nulla facilisi. Ut accumsan dolor et  turpis. Donec ultrices. In hac habitasse platea dictumst. Nulla  pharetra elit id est. Integer a ipsum. Aliquam auctor. Ut ullamcorper  quam ut urna.</td>
  </tr>
</table>
</body>
</html>
El error que da IE6 es:

Cita:
IE6 dice: 'className' es nulo o no es un objeto
Y lo da en la línea 24, que es la del alert que usé para debugear:
Código:
alert('i vale ' + i + ' y tiene que llegar a ' + ((cantidad_filas * 2 - 1) - 1) + '\nLa clase se llama: ' + filas[i].className);
Otra cosa... vean la diferencia entre el alert de FF y el de IE... En FF la variable i toma los valores 0, 1, 2, 3 y 4 mientras que en IE la misma variable vale 0, 1 y 2! Ah, por supuesto que filas[i].className viene vacío o nulo...

¿Qué se puede hacer?



Edit: Usa dos imágenes que son estas:
images/flecha_abajo.gif:
images/flecha_arriba.gif:

Última edición por AlZuwaga; 02/08/2007 a las 14:53 Razón: Para aclarar que está solucionado
  #2 (permalink)  
Antiguo 01/08/2007, 17:28
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: IE6 dice: 'className' es nulo o no es un objeto

Bueno, me ha costado un poquito pero he dado con la "solución":

Tienes que cambiar en la función prepara_tabla() ésto:
Código PHP:
filas[i].setAttribute('class''az_fila_origen'); 
Por ésto:
Código PHP:
filas[i].className 'az_fila_origen'
Si es que luego quieres mirarlo según className en crea_copias():
Código PHP:
if(filas[i].className == laClase){ 


Evidentemente es algo que no se entiende, y que hay que hacerlo para que nuestro amigo el IE entienda bien. A este navegador hay que tratarlo con más mimo.


En IE tomaba 0,1,2,3,4 la variable i, pero en la 3 daba error porque filas.length sería 3 (0,1,2) y al no añadir filas, no se pueden acceder a ellas.



Te recomiendo hacer los bucles en crea_copias() igual que en prepara_tabla() si es que vas a modificar la cantidad de las filas, es decir:
Código PHP:
    var tabla document.getElementById('mi_tabla');
    var 
filas tabla.rows;
    
//var cantidad_filas = filas.length;
    
for(0tabla.rows.lengthi++){ 
Así comprobará todo el rato en cada iteración tabla.rows.length y no habrá distinciones si crea las filas o no las crea. El bucle nunca tendrá elementos de más o de menos (además conseguirás mas legibilidad).



Por otra parte me he dado cuenta que también IE se lleva mal con la propiedad .textContent, que no te dará ningún valor (undefined) y a la que tampoco podrás asignarle nada (y que haga efecto quiero decir). Es una buena alternativa .innerHTML.

He visto más problemas con el 'inherit', y sobre todo aplicando el colspan, a lo que no he sabido darte respuesta.




Espero que no te salgan muchos más líos. En FF por lo menos lo he visto y es un script con un resultado muy bonito. A ver si lo consigues en IE y lo posteas!


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.
  #3 (permalink)  
Antiguo 02/08/2007, 11:02
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 9 meses
Puntos: 535
Re: IE6 dice: 'className' es nulo o no es un objeto

Genial! No lo he intentado aún, pero en cuanto tenga un tiempo libre pongo manos a la obra. Gracias!
  #4 (permalink)  
Antiguo 02/08/2007, 14:57
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 9 meses
Puntos: 535
Re: SOLUCIONADO: 'className' es nulo o no es un objeto

Gracias derkenuke!! Me fue de muchísima ayuda tu respuesta.
Pude solucionar todos los problemas, y lo dejé funcionando en IE. Acá lo dejo para el que lo quiera usar:

Código:
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Manipular una tabla</title>
<script type="text/javascript">
function prepara_tabla(){
	var tabla = document.getElementById('mi_tabla');
	var filas = tabla.rows;
	for(i = 0; i < filas.length; i++){
		la_celda = filas[i].cells[filas[i].cells.length - 1];
		if(la_celda.nodeName.toLowerCase() == 'td'){
			filas[i].className = 'az_fila_origen';
		}
	}
	crea_copias('az_fila_origen');
}


function crea_copias(laClase){
	var tabla = document.getElementById('mi_tabla');
	var filas = tabla.rows;
	for(i = 0; i < tabla.rows.length; i++){
		if(filas[i].className == laClase){
			la_celda = filas[i].cells[filas[i].cells.length - 1];
			nuevo_row = document.createElement('tr');
				nuevo_cell = document.createElement('td');
				nuevo_cell.colSpan = 5;
				nuevo_cell.style.whiteSpace = 'normal';
					nuevo_cell_texto = document.createTextNode(la_celda.innerHTML);
				nuevo_cell.appendChild(nuevo_cell_texto);
			nuevo_row.style.display = 'none';
			nuevo_row.className = 'azNuevaFila';
			nuevo_row.appendChild(nuevo_cell);
			la_celda.innerHTML = '';
			nueva_imagen = document.createElement('img');
			nueva_imagen.setAttribute('src', 'images/flecha_abajo.gif');
			nueva_imagen.onclick = function(){muestra_oculta(this);};
			nueva_imagen.onmouseover = function(){this.style.cursor = 'pointer';};
			la_celda.appendChild(nueva_imagen);
			// comienza código de caricatos para emular un insertAfter \\
			if(filas[i].parentNode.lastChild == filas[i]){
				filas[i].parentNode.appendChild(nuevo_row);
			}
			else{
				filas[i].parentNode.insertBefore(nuevo_row, filas[i].nextSibling);
			}
			// finaliza código de caricatos para emular un insertAfter \\
		}
	}
}

function muestra_oculta(elemento){
	la_fila = elemento.parentNode.parentNode.nextSibling;
	if(la_fila.style.display == 'none'){
		la_fila.style.display = '';
		elemento.src = 'images/flecha_arriba.gif';
	}
	else{
		la_fila.style.display = 'none';
		elemento.src = 'images/flecha_abajo.gif';
	}
}

window.onload = prepara_tabla;
</script>
<style type="text/css">
<!--
#mi_tabla {
	border-collapse: collapse;
	font-family: Georgia, "Times New Roman", Times, serif;
	width: 650px;
}

#mi_tabla th {
	background: #CCCCCC;
}

#mi_tabla td, #mi_tabla th {
	border: 1px solid #666666;
	padding: 5px;
}

#mi_tabla td {
	vertical-align: top;
	white-space: nowrap;
}

.azNuevaFila{
	background: #F7F7F7;
	color: #333333;
	border-bottom: 5px solid #666666;
	font-size: 12px;
}
-->
</style>
</head>

<body>
<h1>Manipular una tabla</h1>
<table id="mi_tabla" cellspacing="1">
  <tr>
    <th scope="col">Pel&iacute;cula</th>
    <th scope="col">Director</th>
    <th scope="col">Escritores</th>
    <th scope="col">G&eacute;nero</th>
    <th scope="col">Sin&oacute;psis</th>
  </tr>
  <tr>
    <td>El extra&ntilde;o mundo de Yack </td>
    <td>Henry Selick</td>
    <td>Tim Burton, Michael McDowell</td>
    <td>Animaci&oacute;n, Familia, Fantas&iacute;a, Musical</td>
    <td>Jack Skellington (The pumpkin king) lives in halloweentown and as usual he celebrates haloween, but he's bored and finds a mysterious forest with 6 doors he opens the christmas tree one and discovers christmastown. The Haloween town residents are worried and go searching for jack until he comes home and calls a town meeting where he tells the townfolk about his new discovery and a mysterious man nicknamed &quot;Santy claus&quot;. After a long researching process he finds out what christmas really means. He gives everyone a job for his own version of christmas until sally (his number 1 admirer) tells him that it will be a HUGE disaster ! He does not listen and tells the Trick or Treat kids to kidnap Santy Claus and to not tell oogie boogie (the evil Dude !!) about his plan. When he sets of on his slay he ends up being blown up out of the sky and going back to haloween town to save sally and santy claus from oogie boogie's lair.</td>
  </tr>
  <tr>
    <td>Mars Attacks!</td>
    <td>Tim Burton</td>
    <td>Len Brown, Woody Gelman</td>
    <td>Acci&oacute;n, Comedia, Fantas&iacute;a, Sci-Fi</td>
    <td>The Martians decide to attack our planet and devastate everything. Why? Because it's fun!!! They enjoy killing people and destroy buildings; they even play bowling with the statues at Easter Isles and pose for photos in front of temples as they are blowing up. Will somebody find a way to stop them or will everyone die in the war with these short, big-brained aliens?</td>
  </tr>
  <tr>
    <td>Charly y la f&aacute;brica de chocolates </td>
    <td>Tim Burton</td>
    <td>Roald Dahl, John August</td>
    <td>Aventuras, Comedia, Familia, Fantas&iacute;a</td>
    <td>Charlie Bucket comes from a poor family, and spends most of his time dreaming about the chocolate that he loves but usually can't afford. Things change when Willy Wonka, head of the very popular Wonka Chocolate empire, announces a contest in which five gold tickets have been hidden in chocolate bars and sent throughout the country. The kids who find the tickets will be taken on a tour of Wonka's chocolate factory and get a special glimpse of the wonders within. Charlie miraculously finds a ticket, along with four other children much naughtier than him. The tour of the factory will hold more than a few surprises for this bunch.</td>
  </tr>
</table>
</body>
</html>

Cita:
En FF por lo menos lo he visto y es un script con un resultado muy bonito. A ver si lo consigues en IE y lo posteas!
Qué emoción
Es la primera vez que me dicen que algo esta bonito
  #5 (permalink)  
Antiguo 02/08/2007, 15:13
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 6 meses
Puntos: 2135
Re: SOLUCIONADO: 'className' es nulo o no es un objeto

Para los que quieran ver y no bajar el codigo les dejo una imagen:


Ciertamente esta muy padre tu script y funciona muy bien si no tienes javascript
  #6 (permalink)  
Antiguo 02/08/2007, 15:20
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 9 meses
Puntos: 535
Re: SOLUCIONADO: 'className' es nulo o no es un objeto

Mmm... no, hay algo que no me gusta... el white-space: nowrap se lo voy a dar por JS y no por estilos...
porque al desactivarlo la tabla se expande horrores hacia la derecha.

Última edición por AlZuwaga; 02/08/2007 a las 15:27
  #7 (permalink)  
Antiguo 02/08/2007, 15:25
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: SOLUCIONADO: 'className' es nulo o no es un objeto

Eso es, ahora sí que funciona. He tomado nota de colSpan (había probado sólo colspan...).

Otro detalle es que no hace falta que cambies el cursor cada vez que se hace onmouseover, me refiero a la línea:
Código PHP:
nueva_imagen.onmouseover = function(){this.style.cursor 'pointer';}; 
Que basta con hacer
Código PHP:
nueva_imagen.style.cursor 'pointer'
Porque la propiedad cursor de CSS actúa en cada elemento, cuando se sale del elemento ya no actúa (sino tendrías que haber puesto un onmouseout, pero sólo hay que poner onmouseover y onmouseout si vas a cambiar document.style.cursor, lo cual no tiene sentido).

Por cierto, no se ve el borde gordo inferior de la clase azNuevaFila en IE6, será cosa del CSS. Lo que más me fastidia de IE6 (sí, antes de su implementación javascript) es su manejo de CSS.


En conjunto lo he visto bonito, pero cuidado con el ancho de la tabla si no se tiene javascript activado, y creo que ya lo tendríamos completo.


Un saludo Al Zuwaga! Muy buen resultado.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #8 (permalink)  
Antiguo 02/08/2007, 15:37
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 9 meses
Puntos: 535
Re: SOLUCIONADO: 'className' es nulo o no es un objeto

derkenuke, lo del colSpan me di cuenta hoy y lo hice luego de varias horas de darle vueltas al asunto porque IE no lo tomaba...
fue cosa de pensar "¿qué pasa si le pongo la letra s en mayúsculas?"... ¡y funcionó!

Corrigiendo y tomando nota sobre el cursor... (eso me pasa por meterme a hacer cosas sin la idoneidad de base suficiente :p)


Lo del ancho de la tabla me di cuenta, pero lo veo complicado al menos para IE.
En FF fue cuestión de poner...
Código:
filas[i].style.whiteSpace = 'nowrap';
... o sea, asignándole el estilo al <tr> y los <td> lo heredaron... pero en IE no funcionó. Ya veo que le voy a hacer.
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 18:38.