JavaScript: usare il DOM per generare un sommario di pagina

In questo articolo vedremo come creare un sommario di una pagina utilizzando solo JavaScript e senza l'appoggio di alcuna libreria. Lavoreremo con i metodi del DOM per realizzare il nostro scopo e ne descriveremo il funzionamento. Vediamo insieme la nostra implementazione.

La nostra pagina HTML è così strutturata:


<body>

<h2>...</h2>
<p>...</p>
<p>...</p>

<h2>...</h2>
<p>...</p>
<p>...</p>

<h2>...</h2>
<p>...</p>
<p>...</p>

</body>

Il nostro sommario andrà inserito prima dell'intestazione più esterna e dovrà contenere una lista di link con un'ancora che punta all'intestazione corrispondente e il testo impostato sullo stesso valore dell'intestazione a cui fa riferimento.

Il sommario dovrà anche avere un titolo da inserire prima della lista. Quindi dobbiamo:

  1. Assegnare un ID diverso a ciascuna intestazione.
  2. Creare la lista del sommario,
  3. Creare il titolo del sommario.
  4. Popolare la lista di link.
  5. Inserire la lista prima dell'intestazione più esterna.
  6. Inserire il titolo del sommario prima della lista.

Come primo step creiamo un oggetto che gestirà le nostre routine:


var SummaryManager = {

	// qui le routine
	
	init: function() {
	
		// esegue le routine
	
	}
};

Quindi dobbiamo assegnare un ID diverso a ciascuna intestazione:


var SummaryManager = {

	 idify: function() {

        var headings = document.getElementsByTagName('h2'),
            len = headings.length,
            i;

        for (i = 0; i < len; i++) {

            var heading = headings[i];
            heading.setAttribute('id', 'sec-' + (i + 1));


        }

    },
    
    init: function() {
    
    	this.idify();
    
    }

};

Abbiamo sfruttato il contatore del loop per generare sec-1, sec-2 eccetera e usarli come ID delle intestazioni. Il metodo setAttribute() accetta come primo parametro il nome dell'attributo e come secondo il suo valore.

A questo punto possiamo passare alla fase successiva, ossia alla creazione del sommario:


var SummaryManager = {

	 idify: function() {

        var headings = document.getElementsByTagName('h2'),
            len = headings.length,
            i;

        for (i = 0; i < len; i++) {

            var heading = headings[i];
            heading.setAttribute('id', 'sec-' + (i + 1));


        }

    },
    
    linkify: function() {

        var titles = document.getElementsByTagName('h2'),
            target = titles[0],
            list = document.createElement('ul'),
            size = titles.length,
            j, body = document.body,
            summary = document.createElement('h3');
        
        summary.appendChild(document.createTextNode('Summary'));

        for (j = 0; j < size; j++) {

            var title = titles[j];
            var anchor = title.getAttribute('id');
            var text = title.firstChild.nodeValue;
            var li = document.createElement('li');
            var a = document.createElement('a');
            a.setAttribute('href', '#' + anchor);
            a.appendChild(document.createTextNode(text));
            li.appendChild(a);
            list.appendChild(li);


        }

        body.insertBefore(list, target);
        body.insertBefore(summary, list);


    },
    
    init: function() {
    
    	this.idify();
    	this.linkify();
    
    }

};

Per creare elementi si utilizza il metodo createElement(). Questo metodo crea un nuovo elemento nella memoria del browser, ma non lo inserisce ancora nel DOM.

Un altro metodo usato è appendChild(). Questo metodo va invocato sul genitore del nodo che si vuole inserire, che nel nostro caso sono sia nodi di testo che nodi di tipo elemento.

createTextNode() crea appunto nodi di tipo testo. Attenzione quindi: se inserite entità HTML con questo metodo queste ultime verranno visualizzate letteralmente e non espanse (come invece accade quando usate la proprietà innerHTML).

Infine, il metodo insertBefore() ha un funzionamento un pò diverso dagli altri perchè accetta tre parametri:


nodoGenitore.insertBefore(nodoDaInserire, nodoDiRiferimento);

Nel nostro caso il genitore è body, i nodi da inserire sono la lista e il titolo del sommario e i nodi di riferimento sono la prima intestazione della pagina e la lista.

Lanciamo il nostro codice come segue:


SummaryManager.init();​

Potete visionare l'esempio finale in questa pagina

Torna su