Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

pwseo

[Javascript] Gerador de Índice (TOC)

Mensagens Recomendadas

pwseo

Olá,

Estava a mexer para aqui no meu pseudo-site e pensei que seria engraçado ter um script que lesse as tags <h1>...<h6> e fizesse um índice automaticamente. Deixo aqui o código para quem quiser, e peço já agora as vossas opiniões (sou muito novo no que diz respeito a Javascript... só estava habituado a lidar com HTML e CSS)

(function() {
   function goBack(start, levels) {
       if (levels > 0) {
           return (goBack(start.parentNode, levels - 1));
       }
       else {
           return start;
       }
   }

   function incCounter(counter, level) {
       counter[level - 2]++;
   }

   function printCounter(counter, level) {
       s = '';
       for (i = 0; i < level - 1; i++) {
           s = s + counter[i] + '.';
       }
       return s;
   }

   function counterToID(counter, level) {
       s = printCounter(counter, level);
       s = s.replace(/\.(\d)/g, "-$1").replace(/\.$/, "");
       return s;
   }

   function maketoc() {

       function recurseheaders(start, previous, counter) {
           if (start == null) return;
           if ((start.nodeType == 1) && (start.tagName.match(/h\d/i))) {
               incCounter(counter, start.tagName.charAt(1));
               li = document.createElement("li");
               a = document.createElement("a");
               span = document.createElement("span");
               span.appendChild(document.createTextNode(printCounter(counter, start.tagName.charAt(1)) + " "));
               li.appendChild(span);
               a.appendChild(document.createTextNode((start.textContent ? start.textContent : start.innerText)));
               a.setAttribute("href", "#sec-" + counterToID(counter, start.tagName.charAt(1)));
               li.appendChild(a);
               start.setAttribute("id", "sec-" + counterToID(counter, start.tagName.charAt(1)));

               if (previous) {
                   if (previous.level < parseInt(start.tagName.charAt(1))) {
                       previous.appendChild(li);
                   }
                   else {
                       goBack(previous, (previous.level - start.tagName.charAt(1)) + 1).appendChild(li);
                   }
               }
               else {
                   document.getElementById("toc").appendChild(li);
               }
               previous = li;
               previous.level = parseInt(start.tagName.charAt(1));
           }
           recurseheaders(start.nextSibling, previous, counter);
       }

       toc = document.createElement("ul");
       toc.setAttribute("id", "toc");
       document.getElementById("content").insertBefore(toc, document.getElementById("content").firstChild);

       recurseheaders(document.getElementById("content").firstChild, undefined, new Array(0, 0, 0, 0, 0, 0));
   }

   if (window.addEventListener) {
       window.addEventListener("load", maketoc, false);
   }
   else {
       window.attachEvent("onload", maketoc);
   }
})();

Atenção... isto pesquisa os elementos <h1>..</h6> dentro de um elemento com id "#content" pois é assim que tenho o meu site.

Peço desculpa pela falta de comentários... mas foi feito à pressa. Aguardo então as vossas críticas :)

  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

Uma das coisas que este script tinha de mal era a sua falta de suporte para o Internet Explorer... Após conseguir um pc com IE livre, estive a pesquisar e a experimentar um pouco... pelo que vi, o IE não sabe o que é addEventListener nem textContent de um elemento.

por isso:

// esta linha:
a.appendChild(document.createTextNode(start.textContent));
// passa a ser assim:
a.appendChild(document.createTextNode((start.textContent ? start.textContent : start.innerText)));

// e esta linha:
window.addEventListener("load", maketoc, false);
// desdobra-se em:
if (window.addEventListener) {
    window.addEventListener("load", maketoc, false);
}
else {
    window.attachEvent("onload", maketoc);
}

Já efectuei estas alterações no script acima :) (Testei no IE6)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.