Quante volte vi è capitato di navigare per la rete con Internet Explorer 7 (o la 8 per chi avesse questo “privilegio”) e di scontrarvi con un finestrella di dialogo di windows che vi dice “Internet Explorer non può aprire il sito Internet” (o in inglese “Internet Explorer cannot open the Internet site”). L’unica cosa che ci resta da fare è cliccare su OK. Ma, haimé, l’operazione non porta a nulla, solo ad una pagina bianca senza contenuto.

IE 7 non offre molte informazioni sulla natura del problema, anche a causa del suo pessimo sistema di ging. Qualcosa di molto più utile è stato fatto con IE 8, ed è proprio grazie a quest’ultimo che si è riusciti ad individuare la natura, nonché la soluzione al problema.

Con IE 8 l’errore indicato è il seguente:

Webpage Script Errors

User Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.5.21022; .NET CLR 3.0.04506)
Timestamp: Fri, 18 Jul 2008 16:19:19 UTC
Message: HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917)
Line: 0
Char: 0
Code: 0

Come sfruttare questo migliorato sistema di debugging e, soprattutto, come risolvere questo problema?

HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917)

Il messaggio d’errore riporta un dato molto importante e cioè, la dicitura . Questa è la codifica ufficiale Microsoft (Knowledge Base, ndr.) per i problemi noti ed eventualmente per le soluzioni. Ciò significa che basta per lo meno fare una ricerca su Google per recuperare tutto ciò che di noto c’è in rete. Inoltre ci fa comprendere che si tratta di un’anomalia che riguarda solo IE; ed infatti, su altri tipi di browser non sembrano esserci problemi.

Il problema si verifica quando:

  1. Il file HTML è in via di ;
  2. Uno JavaScript è in esecuzione e tenta di modificare il codice HTML utilizzando DOM;
  3. Lo script tenta di aggiungere o rimuovere un elemento contentuto in un TAG non ancora chiuso.

In soldoni, se il parser del browser sta analizzando la pagina ed uno JavaScript sta modificando un TAG contenuto all’interno di un altro di cui il parser non ha ancora incontrato la chiusura all’interno del codice; in questa condizione si verifica il problema.

Il seguente codice genera l’errore a cui ci riferiamo:

<HTML>   
         <body>    
                 <div>    
                         <script type="text/javascript">    
                         var newElem = document.createElement('foo');    
                         document.body.appendChild(newElem);    
                         </script>    
                 </div>    
         </body>    
 </html>

Individuata la natura del problema, possiamo correre ai ripari. Ci sono, infatti, almeno 4 possibili soluzioni a cui possiamo ricorrere.

1.

Eseguiamo lo script solo dopo che il parser ha terminato il suo lavoro. Lo si può fare inserendo il codice all’interno di una funzione JavaScript che poi faremo eseguire dall’evento window.onload che viene evocato quando il parser termina il suo compito.

2.

Aggiungiamo l’attributo defer=”defer” al TAG JavaScript come nell’esempio seguente:

<script defer="defer" type="text/javascript">   
 var newElem = document.createElement('foo');    
 document.body.appendChild(newElem);    
 </script>

Questo mette in stand-by il codice fintanto che il parser non ha terminato il suo lavoro.

3.

Evitiamo di fare modifiche ad elementi HTML molto nidificati.

4.

Spostiamo lo JavaScript che è causa del problema, alla fine della nostra pagina HTML, subito prima del TAG </body>.

La prima soluzione è decisamente quella che reputo più elegante in termini di progettazione del codice, tuttavia anche le altre risolvono egreggiamente il problema. Per cui, la scelta tra le quattro è puramente personale e molto spesso di natura pratica.