Diretiva AngularJS para gerar um índice analítico
-
21-12-2019 - |
Pergunta
Imagine um texto HTML que contém títulos (h1-h6).Na minha situação também está presente como DOM em uma página html.Então, usando jQuery, eu faria algo como $('.text').find('h1,h2,h3,h4,h5,h6')
para extrair todas as manchetes.
Mas não quero usar jQuery ou qualquer outro framework pesado.Como posso fazer isso com angularJS?Lembre-se de que preciso dos títulos na ordem correta para exibi-los como um índice.
Solução
Então aqui está minha solução final.A parte ng-model é usada para atualizar os títulos quando o texto é atualizado.
.directive('tableOfContents', function(){
return {
restrict:'A',
require:'?ngModel',
link : function(scope, elm, attrs,ngModel) {
function updateHeadlines() {
scope.headlines=[];
angular.forEach(elm[0].querySelectorAll('h1,h2,h3,h4,h5,h6'), function(e){
scope.headlines.push({
level: e.tagName[1],
label: angular.element(e).text(),
element: e
});
});
}
// avoid memoryleaks from dom references
scope.$on('$destroy',function(){
scope.headlines=[];
});
// scroll to one of the headlines
scope.scrollTo=function(headline){
headline.element.scrollIntoView();
}
// when the html updates whe update the headlines
ngModel.$render = updateHeadlines;
updateHeadlines();
}
}
})
Uso:
<a ng-repeat="headline in headlines" ng-click="scrollTo(headline)">{{headline.label}}</a>
<div table-of-contents ng-model="html">{{html}}</div>
Outras dicas
Você está com sorte e deve poder usar elemento angular quase exatamente da mesma maneira que você usaria o jQuery.
angular.element('h1')
vai encontrar h1
elementos.
Você pode encontrar os elementos que possuem a classe ".text" usando
angular.element(document.querySelectorAll(".text"));