Ver Mensaje Individual
  #42 (permalink)  
Antiguo 16/05/2008, 12:34
Avatar de Panino5001
Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 5 meses
Puntos: 834
Respuesta: HOWTO: Ejecutar javascript que viene de ajax

Antes, cuando tenía que evaluar código javascript incluído en un responseText, lo hacía de esta manera:
Código:
<script>
function SetContainerHTML(id_contenedor,responseText)
{
mydiv = document.getElementById(id_contenedor);
mydiv.innerHTML = responseText;
var elementos = mydiv.getElementsByTagName('script');
for(i=0;i<elementos.length;i++) {
var elemento = elementos[i];
nuevoScript = document.createElement('script');
nuevoScript.text = elemento.innerHTML;
nuevoScript.type = 'text/javascript';
if(elemento.src!=null && elemento.src.length>0)
{nuevoScript.src = elemento.src;}
elemento.parentNode.replaceChild(nuevoScript,elemento);
}
}

</script>
Pero al parecer, Explorer 7 ya no incluye los tags script dentro de la propiedad innerHTML, por lo cual, esa técnica ya no funciona, a menos que reemplacemos los tags scripts por otros y volvamos luego a recrearlos.
Así que me decanté por la opción de las regExp, como la sugerida por MaBoRaK, en la cual se fundamenta toda la idea, pero con algunas diferencias: usando un único prototype para realizar todo el proceso, ya sea para extraer scripts internos y/o externos, e incluyéndos con DOM, en lugar de evaluarlos.
El código utilizado para esto es el siguiente:
Código:
String.prototype.tratarResponseText=function(){
	var pat=/<script[^>]*>([\S\s]*?)<\/script[^>]*>/ig;
	var pat2=/\b\s+src=[^>\s]+\b/g;
	var elementos = this.match(pat) || [];
	for(i=0;i<elementos.length;i++) {
		var nuevoScript = document.createElement('script');
		nuevoScript.type = 'text/javascript';
		var tienesrc=elementos[i].match(pat2) || [];
		if(tienesrc.length){
			nuevoScript.src=tienesrc[0].split("'").join('').split('"').join('').split('src=').join('').split(' ').join('');
		}else{
			var elemento = elementos[i].replace(pat,'$1','');
			nuevoScript.text = elemento;
		}
		document.getElementsByTagName('body')[0].appendChild(nuevoScript);
	}
	return this.replace(pat,'');
}
Y un ejemplo de uso sería este:
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>test</title>
<script>
function $(id){return document.getElementById(id);}
function http(){
	if(window.XMLHttpRequest){
		return new XMLHttpRequest();	
	}else{
		try{
			return new ActiveXObject('Microsoft.XMLHTTP');
		}catch(e){
			alert('nop');
        	return false;
		}	
	}
}
String.prototype.tratarResponseText=function(){
	var pat=/<script[^>]*>([\S\s]*?)<\/script[^>]*>/ig;
	var pat2=/\b\s+src=[^>\s]+\b/g;
	var elementos = this.match(pat) || [];
	for(i=0;i<elementos.length;i++) {
		var nuevoScript = document.createElement('script');
		nuevoScript.type = 'text/javascript';
		var tienesrc=elementos[i].match(pat2) || [];
		if(tienesrc.length){
			nuevoScript.src=tienesrc[0].split("'").join('').split('"').join('').split('src=').join('').split(' ').join('');
		}else{
			var elemento = elementos[i].replace(pat,'$1','');
			nuevoScript.text = elemento;
		}
		document.getElementsByTagName('body')[0].appendChild(nuevoScript);
	}
	return this.replace(pat,'');
}

function SetContainerHTML(id_contenedor,responseText){
	var mydiv = $(id_contenedor);
	mydiv.innerHTML = responseText.tratarResponseText();
}
function cargarPagina(url,contenedorId){
var H=new http();
H.open('get',url+'?'+Math.random(),true);
H.onreadystatechange=function(){
	if(H.readyState==4){
		SetContainerHTML(contenedorId,H.responseText);
		H.onreadystatechange=null;
	}else{
		$(contenedorId).innerHTML='cargando...';
	}
}
H.send(null);
}
window.onload=function(){
	cargarPagina('pagina2.php','pp');
}
</script>  
</head>

<body>
<div id="pp"></div>
</body>
</html>

Última edición por Panino5001; 16/05/2008 a las 13:07