25 novembre 2008

Interpetare il Javascript incluso in un DIV mediante innerHTML con Ajax

Una classica modalità di utilizzo di Ajax è quella in cui in maniera asincrona viene chiamata una pagina (jsp,aspx,php,..) la quale alla fine della propria esecuzione restituisce al controller Ajax l'html ottenuto.
Nella maggiorparte dei casi si tende ad utilizzare tale html per visualizzare nella pagina chiamante il risultato ottenuto in un DIV senza dover ricaricare la pagina.
Un problema in cui si incorre in questa tipologia di approccio è rappresentato dall'interpretazione da parte del browser del javascript che può essere contenuto in questa pagina inclusa all'interno del DIV.
Il problema stà nel fatto che il browser, carica i javascript man mano che carica la pagina, quando in maniera asincrona si và a "riempire" un div mediante la proprietà innerHTML, il browser non si preoccupa di caricare i javascript contenuti.

A volte, quando non si ha la necessità di dover generare gli script in maniera dinamica, è possibile ovviare a tale problema includendo il codice all'interno della pagina principale. In altri casi è necessario costruire gli script in maniera dinamica, quindi può essere davvero utile adottare la seguente strategia per poter risolvere il problema.
Il sorgente seguente rappresenta la pagina principale.
<!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>
<title>Pagina senza titolo</title>
<script type="text/javascript" src="../js/libreria.js"></script>
<script language="javascript" type="text/javascript">
// <!CDATA[

function Button1_onclick()
{
//faccio la richiesta alla pagina php o jsp che restituisce
//<p>Ciao</p><_script language=\"javascript\">alert('pippo')</_script>
ajax("a.asp", onload);
function onload()
{
//t contiene la risposta
var t = this.request.responseText;

//execJS esegue javascript contenuto in t e restituisce
//t senza javascript
t = execJS(t);

//finalmente metto t 'pulito' dento il div
$("div1").innerHTML = t;

}
}



// ]]>
</script>
</head>
<body>
<input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />
<div id="div1"></div>
</body>
</html>


La funzione javascript execJS è definita così:
function execJS(t)
{
var p1 = 0, p2 = 0, p3 = 0, p4 = 0;
p1 = t.indexOf("<" + "script", 0);
if(p1 == -1) return t;

p2 = t.indexOf(">", p1 + 7) + 1;
p3 = t.indexOf("<" + "/script>", p2);
p4 = p3 + 9;

var c = t.substring(p2, p3);
var s = document.createElement("script");
s.type = "text/javascript";
s.text = c;
document.getElementsByTagName("head")[0].appendChild(s);

t = t.substring(0, p1) + t.substr(p4);
return execJS(t);

}

Nessun commento: