Foros del Web » Programando para Internet » Javascript » Frameworks JS »

Migrar a ajax

Estas en el tema de Migrar a ajax en el foro de Frameworks JS en Foros del Web. Hola: Desde que me enteré de esta tecnología, decidí probarla y sin dudas puede ser muy útil, aunque ya tengo mis primeros problemas... Quise actualizar ...
  #1 (permalink)  
Antiguo 03/07/2005, 11:18
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 7 meses
Puntos: 1284
Migrar a ajax

Hola:

Desde que me enteré de esta tecnología, decidí probarla y sin dudas puede ser muy útil, aunque ya tengo mis primeros problemas...

Quise actualizar mi galería de imágenes porque la defino a partir de un array de objetos "Foto" que a medida que crece, ralentiza bastante la carga de la página, ya que es un fichero "js" (fotos.js).

Bueno, el ejemplo se puede ver entre la galería del año pasado: http://www.sucaricatura.com/2004/index.html y la versión ajax (sin depurar): http://www.sucaricatura.com/2004/index-ajax.html

Como se puede ver la versión ajax se carga bastante más rápido, pero la cuarta página no se ve

El fichero XML que se genera en la llamada es éste: http://www.sucaricatura.com/2004/Aja...p?rango=90-119
... y no tengo idea de lo que pueda estar mal para que no se renderice.

En sucesivos mensajes, explicaré paso a paso lo que he hecho.

Por cierto, en la versión actual no he tenido problemas (hay que cambiar el 2004 por 2005 en los enlaces, y el rango -hasta ahora solo llevo unas 70 fotos-).


Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #2 (permalink)  
Antiguo 03/07/2005, 18:34
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 7 meses
Puntos: 1284
Siguiendo con la experiencia...

La idea principal era evitar bajar el fichero fotos.js, y para ello pensé que desde el servidor podría obtener datos concretos... y en primer lugar, pensé en obtener la longitud del array de fotos, pero solo tenía el "ficherito" fotos.js... y después de preguntar en "php" me indicaron cómo conseguir que cada línea se convirtiera en un índice de un array con la función file (gracias jam)

Luego apliqué la función explode para otener el array, y a partir de ahí, cada elemento... Bueno, la parte php la voy a obviar en este foro... aunque el resultado se puede ver en el mensaje anterior.

Resumiendo un poco, mi intención era en vez de usar un tag script que cargase las fotos, gestionar el fichero fotos.js desde el servidor (un fichero php) y obtener con ajax en un principio la longitud del array de fotos y después todos las fotos de forma paginada... el resultado se puede ver aquí: http://www.sucaricatura.com/2004/AjaxFotos.php

Y las fotos en forma paginada se puede ver en los enlaces anteriores.

No tengo idea porqué no aparece la 4º página... seguiré investigando e informando.

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo

Última edición por caricatos; 03/07/2005 a las 18:48
  #3 (permalink)  
Antiguo 09/07/2005, 16:22
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 7 meses
Puntos: 1284
Hola:

Ya funciona correctamente, y creo que es bueno tomar nota del error. Se trata de el uso de bucles con números recibidos como texto...
Cada una de las capas recibe un valor inicial y otro final, que en el caso de un bucle, se puede resolver con indices de menor a mayor(por ejemplo "0"-"29"), pero "90"-"119" no cuela y para solucionarlo tan solo debe convertirse a números [parseInt("90") y parseInt("119")]

Bueno, desglosaré un poco el paso a paso de la migración.

Resulta que el fichero de la galería (fotos.js) consta de 2 tipos de líneas:
Código:
var galeria = new Array();
y
Código:
galeria[0] = new Foto('fotos/20040000.jpg', '360x480', '10/1/2004', 'Skateboard', 'ef=1,risas=1,env=1');
Mi primer reto, era conseguir saber el tamaño del array galeria y pensé que leyendo línea a línea el fichero y por cada línea hacer un explode (php) sobre las comillas:

Código:
<?php
header('Content-Type: text/xml');
?>
<?php
function total() {
$lineas = file("fotos.js");
$n = count($lineas);
for ($i = 0, $j = 0; $i < $n; $i ++)	{
	$resultado = explode("'", $lineas[$i]);
	if (count($resultado) > 1)	{
		$j++;
	}
}
return "<pepe><total>$j</total></pepe>";
}

echo '<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>';

echo total();
?>
Y se puede ver como será el fichero xml resultante:

AjaxFotos.php:
Código:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?> 
<pepe>
<total>469</total> 
</pepe>
Las peticiones javascript se hacen con esta función:

Código:
function pedirXML(sitio, respuesta)	{
	if (window.XMLHttpRequest)	{
		pedido = new XMLHttpRequest();
		pedido.onreadystatechange = respuesta;
		pedido.open("GET", sitio, true);
		pedido.send(null);
	}
	else
		if (window.ActiveXObject)	{
			pedido = new ActiveXObject("Microsoft.XMLHTTP");
			if (pedido)	{
				pedido.onreadystatechange = respuesta;
				pedido.open("GET", sitio, true);
				pedido.send();
			}
		}
}
Y para esta primera petición es:
Código:
pedirXML("AjaxFotos.php", respuestaXMLNFotos);
y la función respuestaXMLNFotos:

Código:
function respuestaXMLNFotos()	{// 
	if (pedido.readyState == 4)	{
		if (pedido.status == 200)	{
			datoTraido = pedido.responseXML.documentElement;
			// éxito: damos valores en blanco al array galería para mostrar luego
			tamGaleria = parseInt(datoTraido.getElementsByTagName('total')[0].firstChild.data);
			//alert(tamGaleria);
			for (var i = 0; i < tamGaleria; i ++)
				galeria[i] = new Foto("", "", "", "", "");
			
			// Buscamos fechas para el menu... y Escribimos las páginas:

			// La petición será:
			var pedir = "AjaxBuscarFechas.php?rango=" + tamPagina;
			// se debe mostrar la última capa
			irCapa = ncapas - 1;
			// la respuesta será procesada por respuestaXMLNRango() 
			pedirXML(pedir, respuestaXMLFechas);
		}
		else	{
			alert("error\n" + pedido.statusText);
		}
	}
}
A partir de aquí se hace la siguiente petición para preparar el menú...
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #4 (permalink)  
Antiguo 09/07/2005, 16:49
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 7 meses
Puntos: 1284
Siguiendo la crónica:

Cuando sabemos el tamaño del array de fotos (no sabemos nada más) llenamos un array vacío de fotos:

Código:
tamGaleria = parseInt(datoTraido.getElementsByTagName('total')[0].firstChild.data);
for (var i = 0; i < tamGaleria; i ++)
	galeria[i] = new Foto("", "", "", "", "");
Sabiendo el tamaño de cada página desde la llamada principal:
Código:
<script type="text/javascript" >
	galeriaPaginada(galeria, "0.28", 10, 3, "laGaleria", "", "popup");
</script>
El tercer parámetro es el número de filas de cada página, y el 4º el número de columnas (en este caso son 30)... y ese valor será el que se pase como rango en la siguiente petición:

Código:
var pedir = "AjaxBuscarFechas.php?rango=" + tamPagina;
// se debe mostrar la última capa
irCapa = ncapas - 1;
// la respuesta será procesada por respuestaXMLNRango() 
pedirXML(pedir, respuestaXMLFechas);
Recibimos la petición en respuestaXMLNRango() a partir de AjaxBuscarFechas.php:

Código:
<?php
header('Content-Type: text/xml');

function fechas($rango) {
	$lineas = file("fotos.js");
	$n = count($lineas);
	echo "<pepe>";
	for ($i = 0, $j = 0; $i < $n; $i ++)	{
		$resultado = explode("'", $lineas[$i]);
		if (count($resultado) > 1)	{
			if (($j % $rango) == 0)
				echo "\n<foto><lugar>$j</lugar><src>$resultado[1]</src><tam>$resultado[3]</tam><fecha>$resultado[5]</fecha><motivo>$resultado[7]</motivo><opciones>$resultado[9]</opciones></foto>";
			if (($j % $rango) == ($rango - 1) || $j == $n - 2)
				echo "\n<foto><lugar>$j</lugar><src>$resultado[1]</src><tam>$resultado[3]</tam><fecha>$resultado[5]</fecha><motivo>$resultado[7]</motivo><opciones>$resultado[9]</opciones></foto>";
			$j++;
		}
	}
	echo "</pepe>";
}

echo '<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>';

$rango = 1;
if (isset($_GET["rango"]))	{
	$rango = (int) $_GET["rango"];
}
  
fechas($rango);
?>
Aparte de la cabecera XML y la etiqueta raíz, devuelve datos de esta clase:
Código:
- <foto>
  <lugar>0</lugar> 
  <src>fotos/20040000.jpg</src> 
  <tam>360x480</tam> 
  <fecha>10/1/2004</fecha> 
  <motivo>Skateboard</motivo> 
  <opciones>ef=1,risas=1,env=1</opciones> 
  </foto>
- <foto>
  <lugar>29</lugar> 
  <src>fotos/20040029.jpg</src> 
  <tam>360x480</tam> 
  <fecha>15/5/2004</fecha> 
  <motivo>Superman</motivo> 
  <opciones>ef=1,risas=1,env=1</opciones> 
  </foto>
Que servirán para rellenar los elementos de la galería que formán parte del menú de paginación... donde pone lugar será el índice del array y el resto de etiquetas llenaran los objetos fotos que se corresponden con las fotos primera y última de cada página: (0-29, 30-59, 60-89...)

Y la función javascript que la procesa:
Código:
function respuestaXMLFechas()	{// 
	if (pedido.readyState == 4)	{
		if (pedido.status == 200)	{
			datoTraido = pedido.responseXML.documentElement;
			// averiguamos el tamaño para el bucle:
			elementos = datoTraido.getElementsByTagName('foto');
			tamTraido = elementos.length;
			//alert ("trajimos " + tamTraido + " datos");
			// asignamos los valores al array galeria...
			for (var i = 0; i < tamTraido; i++)
				with(galeria[elementos[i].getElementsByTagName("lugar")[0].firstChild.data])	{
					URL = elementos[i].getElementsByTagName("src")[0].firstChild.data;
					tam = elementos[i].getElementsByTagName("tam")[0].firstChild.data;
					fecha = elementos[i].getElementsByTagName("fecha")[0].firstChild.data;
					comentario = elementos[i].getElementsByTagName("motivo")[0].firstChild.data;
					opciones = elementos[i].getElementsByTagName("opciones")[0].firstChild.data;
				}
			// y escribimos la galería buscando la última página
			document.getElementById(capaBase).innerHTML = 
				_galeriaPaginada(galeria, miniatura, FILASxPAGINA, COLUMNASxFILA, capaBase, lasDimensiones, destino);

			// El índice menor será ncapas * tamPagina:
			var indiceMenor = (ncapas - 1) * tamPagina;

			// El índice mayor será tamGaleria - 1:
			var indiceMayor = tamGaleria - 1;
			// La petición será:

			var pedir = "AjaxBuscarFotos.php?rango=" + indiceMenor + "-" + indiceMayor;
			irCapa = ncapas - 1;
			pedirXML(pedir, respuestaXMLRango);
		}
		else	{
			alert("error\n" + pedido.statusText);
		}
	}
}
Como se puede ver, se hace la última petición del inicio con:
Código:
var pedir = "AjaxBuscarFotos.php?rango=" + indiceMenor + "-" + indiceMayor;
irCapa = ncapas - 1;
pedirXML(pedir, respuestaXMLRango);
Y la respuesta escribe la capa correspondiente:
Código:
function respuestaXMLRango()	{// 
	if (pedido.readyState == 4)	{
		if (pedido.status == 200)	{
			datoTraido = pedido.responseXML.documentElement;
			// averiguamos el tamaño para el bucle:
			elementos = datoTraido.getElementsByTagName('foto');
			tamTraido = elementos.length;
			//alert ("trajimos " + tamTraido + " datos");
			// asignamos los valores al array galeria...
			for (var i = 0; i < tamTraido; i++)
				with(galeria[elementos[i].getElementsByTagName("lugar")[0].firstChild.data])	{
					URL = elementos[i].getElementsByTagName("src")[0].firstChild.data;
					tam = elementos[i].getElementsByTagName("tam")[0].firstChild.data;
					fecha = elementos[i].getElementsByTagName("fecha")[0].firstChild.data;
					comentario = elementos[i].getElementsByTagName("motivo")[0].firstChild.data;
					opciones = elementos[i].getElementsByTagName("opciones")[0].firstChild.data;
				}
			// y escribimos la capa correspondiente
			escribirCapa(irCapa, 
				elementos[0].getElementsByTagName("lugar")[0].firstChild.data,
				elementos[tamTraido - 1].getElementsByTagName("lugar")[0].firstChild.data);
			// y actualizamos el array vistas
			vistas[irCapa] = true;
			// y mostramos la capa:
			document.getElementById(capaBase + irCapa).style.display = "block";
			
		}
		else	{
			alert("error\n" + pedido.statusText);
		}
	}
}
Las siguientes peticiones se hacen cada vez que se quiere mostrar una página que no estuviera cargada...

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #5 (permalink)  
Antiguo 09/07/2005, 16:57
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 7 meses
Puntos: 1284
Por último el fichero completo de la galería en ajax: http://www.sucaricatura.com/2004/galeria-ajax.js

Se puede ver en: http://www.sucaricatura.com/2004/index-ajax.html

y para compararlo con la versión anterior: http://www.sucaricatura.com/2004/index.html

Creo que se gana bastante tiempo al cargarse la página. Pienso que se puede mejorar, pero para empezar me parece que es un buen trabajo.

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #6 (permalink)  
Antiguo 09/07/2005, 23:49
 
Fecha de Ingreso: noviembre-2003
Mensajes: 444
Antigüedad: 21 años
Puntos: 0
eres grande tio
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 04:36.